From 66aaabf4ae05508ea8fa223c84b7a78aa754c7f9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 1 Mar 2008 00:05:12 -0500 Subject: X86: Don't map the local APIC into the physical address space in SE mode. --HG-- extra : convert_revision : b7103974b12130bbf43583c4cb5294b808add208 --- src/arch/x86/tlb.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index a87abf212..3e720c9ae 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -592,6 +592,7 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) req->setPaddr(vaddr); } // Check for an access to the local APIC +#if FULL_SYSTEM LocalApicBase localApicBase = tc->readMiscRegNoEffect(MISCREG_APIC_BASE); Addr baseAddr = localApicBase.base << 12; Addr paddr = req->getPaddr(); @@ -733,6 +734,7 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) } req->setPaddr(regNum * sizeof(MiscReg)); } +#endif return NoFault; }; -- cgit v1.2.3 From a245b0eedfac7ba25656661868fbf3bd8eaf1ccd Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 6 Mar 2008 20:37:28 -0500 Subject: X86: Refine the local APIC. --HG-- extra : convert_revision : 2789c54ed555fed2f2a333fcc7dc6454f294ebf2 --- src/arch/x86/miscregfile.cc | 59 +++++++++++++++------------------------------ src/arch/x86/miscregs.hh | 2 ++ 2 files changed, 22 insertions(+), 39 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc index 3b4dc3407..5d75af0cf 100644 --- a/src/arch/x86/miscregfile.cc +++ b/src/arch/x86/miscregfile.cc @@ -156,12 +156,8 @@ MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc) case MISCREG_APIC_DESTINATION_FORMAT: panic("Local APIC Destination Format register unimplemented.\n"); break; - case MISCREG_APIC_SPURIOUS_INTERRUPT_VECTOR: - panic("Local APIC Spurious Interrupt Vector" - " register unimplemented.\n"); - break; case MISCREG_APIC_ERROR_STATUS: - panic("Local APIC Error Status register unimplemented.\n"); + regVal[MISCREG_APIC_INTERNAL_STATE] &= ~ULL(0x1); break; case MISCREG_APIC_INTERRUPT_COMMAND_LOW: panic("Local APIC Interrupt Command low" @@ -171,25 +167,6 @@ MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc) panic("Local APIC Interrupt Command high" " register unimplemented.\n"); break; - case MISCREG_APIC_LVT_TIMER: - panic("Local APIC LVT Timer register unimplemented.\n"); - break; - case MISCREG_APIC_LVT_THERMAL_SENSOR: - panic("Local APIC LVT Thermal Sensor register unimplemented.\n"); - break; - case MISCREG_APIC_LVT_PERFORMANCE_MONITORING_COUNTERS: - panic("Local APIC LVT Performance Monitoring Counters" - " register unimplemented.\n"); - break; - case MISCREG_APIC_LVT_LINT0: - panic("Local APIC LVT LINT0 register unimplemented.\n"); - break; - case MISCREG_APIC_LVT_LINT1: - panic("Local APIC LVT LINT1 register unimplemented.\n"); - break; - case MISCREG_APIC_LVT_ERROR: - panic("Local APIC LVT Error register unimplemented.\n"); - break; case MISCREG_APIC_INITIAL_COUNT: panic("Local APIC Initial Count register unimplemented.\n"); break; @@ -261,11 +238,22 @@ void MiscRegFile::setReg(int miscReg, panic("Local APIC Destination Format register unimplemented.\n"); break; case MISCREG_APIC_SPURIOUS_INTERRUPT_VECTOR: - panic("Local APIC Spurious Interrupt Vector" - " register unimplemented.\n"); + regVal[MISCREG_APIC_INTERNAL_STATE] &= ~ULL(1 << 1); + regVal[MISCREG_APIC_INTERNAL_STATE] |= val & (1 << 8); + if (val & (1 << 9)) + warn("Focus processor checking not implemented.\n"); break; case MISCREG_APIC_ERROR_STATUS: - panic("Local APIC Error Status register unimplemented.\n"); + { + if (regVal[MISCREG_APIC_INTERNAL_STATE] & 0x1) { + regVal[MISCREG_APIC_INTERNAL_STATE] &= ~ULL(0x1); + newVal = 0; + } else { + regVal[MISCREG_APIC_INTERNAL_STATE] |= ULL(0x1); + return; + } + + } break; case MISCREG_APIC_INTERRUPT_COMMAND_LOW: panic("Local APIC Interrupt Command low" @@ -276,23 +264,16 @@ void MiscRegFile::setReg(int miscReg, " register unimplemented.\n"); break; case MISCREG_APIC_LVT_TIMER: - panic("Local APIC LVT Timer register unimplemented.\n"); - break; case MISCREG_APIC_LVT_THERMAL_SENSOR: - panic("Local APIC LVT Thermal Sensor register unimplemented.\n"); - break; case MISCREG_APIC_LVT_PERFORMANCE_MONITORING_COUNTERS: - panic("Local APIC LVT Performance Monitoring Counters" - " register unimplemented.\n"); - break; case MISCREG_APIC_LVT_LINT0: - panic("Local APIC LVT LINT0 register unimplemented.\n"); - break; case MISCREG_APIC_LVT_LINT1: - panic("Local APIC LVT LINT1 register unimplemented.\n"); - break; case MISCREG_APIC_LVT_ERROR: - panic("Local APIC LVT Error register unimplemented.\n"); + { + uint64_t readOnlyMask = (1 << 12) | (1 << 14); + newVal = (val & ~readOnlyMask) | + (regVal[miscReg] & readOnlyMask); + } break; case MISCREG_APIC_INITIAL_COUNT: panic("Local APIC Initial Count register unimplemented.\n"); diff --git a/src/arch/x86/miscregs.hh b/src/arch/x86/miscregs.hh index d1016d2a9..15ea0d77b 100644 --- a/src/arch/x86/miscregs.hh +++ b/src/arch/x86/miscregs.hh @@ -373,6 +373,8 @@ namespace X86ISA MISCREG_APIC_DIVIDE_COUNT, MISCREG_APIC_END = MISCREG_APIC_DIVIDE_COUNT, + MISCREG_APIC_INTERNAL_STATE, + // "Fake" MSRs for internally implemented devices MISCREG_PCI_CONFIG_ADDRESS, -- cgit v1.2.3 From 48409ca512da9e972b159d45068a1173d2ae1759 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 25 Mar 2008 02:08:54 -0400 Subject: X86: Start implementing the south bridge stuff. --HG-- extra : convert_revision : 92918c05eb3363155d78889bdab17baa8eae9dca --- src/arch/x86/x86_traits.hh | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/x86_traits.hh b/src/arch/x86/x86_traits.hh index d605ce218..f46279c81 100644 --- a/src/arch/x86/x86_traits.hh +++ b/src/arch/x86/x86_traits.hh @@ -90,6 +90,18 @@ namespace X86ISA const Addr PhysAddrPrefixIO = ULL(0x8000000000000000); const Addr PhysAddrPrefixPciConfig = ULL(0xC000000000000000); + + static inline Addr + x86IOAddress(const uint32_t port) + { + return PhysAddrPrefixIO | port; + } + + static inline Addr + x86PciConfigAddress(const uint32_t addr) + { + return PhysAddrPrefixPciConfig | addr; + } } #endif //__ARCH_X86_X86TRAITS_HH__ -- cgit v1.2.3 From b7af65f414d34cb6b3817bc748fd053f505b0fea Mon Sep 17 00:00:00 2001 From: Stephen Hines Date: Tue, 20 May 2008 14:04:53 -0400 Subject: SCons: Fixing SCons bug 2006 issues for non-alpha ISAs --HG-- extra : convert_revision : 26e3edef06d6f82aaf162825c151d18faadd6e72 --- src/arch/mips/SConscript | 3 +++ src/arch/sparc/SConscript | 4 ++++ 2 files changed, 7 insertions(+) (limited to 'src/arch') diff --git a/src/arch/mips/SConscript b/src/arch/mips/SConscript index 8be445c99..844e7ba15 100644 --- a/src/arch/mips/SConscript +++ b/src/arch/mips/SConscript @@ -33,6 +33,9 @@ Import('*') if env['TARGET_ISA'] == 'mips': +# Workaround for bug in SCons version > 0.97d20071212 +# Scons bug id: 2006 M5 Bug id: 308 + Dir('isa/formats') Source('faults.cc') Source('regfile/int_regfile.cc') Source('regfile/float_regfile.cc') diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript index a86c00250..d4d68a6bd 100644 --- a/src/arch/sparc/SConscript +++ b/src/arch/sparc/SConscript @@ -32,6 +32,10 @@ Import('*') if env['TARGET_ISA'] == 'sparc': +# Workaround for bug in SCons version > 0.97d20071212 +# Scons bug id: 2006 M5 Bug id: 308 + Dir('isa/formats') + Dir('isa/formats/mem') Source('asi.cc') Source('faults.cc') Source('floatregfile.cc') -- cgit v1.2.3 From fd3e661cd3c9d6e5424864b3986a51b940ce01eb Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Wed, 11 Jun 2008 10:54:08 -0400 Subject: SCons: Fix more SCons version issues --- src/arch/x86/SConscript | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript index 674cd54c2..09967b0d3 100644 --- a/src/arch/x86/SConscript +++ b/src/arch/x86/SConscript @@ -353,3 +353,17 @@ if env['TARGET_ISA'] == 'x86': # Only non-header files need to be compiled. if not f.path.endswith('.hh'): Source(f) + + # Workaround for bug in SCons version > 0.97d20071212 + # Scons bug id: 2006 M5 Bug id: 308 + from os.path import dirname, join as joinpath + + Dir('isa') + Dir('isa/microops') + Dir('isa/decoder') + Dir('isa/formats') + Dir('isa/insts') + isa_dirs = set(map(lambda x:dirname(x), python_files)) + for d in isa_dirs: + Dir(joinpath('isa/insts', d)) + -- cgit v1.2.3 From 5797ff10160df8fa9f51196753ab702cf190163f Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Wed, 11 Jun 2008 10:54:12 -0400 Subject: X86: Fix building on *BSD hosts --- src/arch/x86/linux/linux.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh index 8a78d5320..8d6468f06 100644 --- a/src/arch/x86/linux/linux.hh +++ b/src/arch/x86/linux/linux.hh @@ -82,7 +82,7 @@ class X86Linux64 : public Linux uint64_t st_mtime_nsec; uint64_t st_ctimeX; uint64_t st_ctime_nsec; - int64_t __unused[3]; + int64_t unused0[3]; } tgt_stat64; static OpenFlagTransTable openFlagTable[]; -- cgit v1.2.3 From 8501a90f59c73896b4eea6d7ce8f1d1cc8685d53 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:39:10 -0400 Subject: X86: Add in some support for the tsc register. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 2 +- src/arch/x86/isa/insts/system/msrs.py | 8 ++++++++ src/arch/x86/isa/microops/regop.isa | 12 +++++++++++- src/arch/x86/isa/operands.isa | 3 ++- src/arch/x86/miscregfile.cc | 8 ++++++++ 5 files changed, 30 insertions(+), 3 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index 8135a1fdb..e2d968c17 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -317,7 +317,7 @@ } 0x06: decode OPCODE_OP_BOTTOM3 { 0x0: Inst::WRMSR(); - 0x1: rdtsc(); + 0x1: Inst::RDTSC(); 0x2: Inst::RDMSR(); 0x3: rdpmc(); 0x4: sysenter(); diff --git a/src/arch/x86/isa/insts/system/msrs.py b/src/arch/x86/isa/insts/system/msrs.py index 1acb4c792..461ed1054 100644 --- a/src/arch/x86/isa/insts/system/msrs.py +++ b/src/arch/x86/isa/insts/system/msrs.py @@ -99,4 +99,12 @@ def macroop WRMSR or t2, t2, t3, dataSize=8 st t2, intseg, [8, t1, rcx], dataSize=8, addressSize=4 }; + +def macroop RDTSC +{ + rdtsc t1 + mov rax, rax, t1, dataSize=4 + srli t1, t1, 32, dataSize=8 + mov rdx, rdx, t1, dataSize=4 +}; ''' diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index e761f0034..03a7515ed 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -1,4 +1,4 @@ -// Copyright (c) 2007 The Hewlett-Packard Development Company +// Copyright (c) 2007-2008 The Hewlett-Packard Development Company // All rights reserved. // // Redistribution and use of this software in source and binary forms, @@ -1018,6 +1018,16 @@ let {{ ''' + class Wrtsc(WrRegOp): + code = ''' + TscOp = psrc1; + ''' + + class Rdtsc(RdRegOp): + code = ''' + DestReg = TscOp; + ''' + class Wrdl(RegOp): code = ''' SegDescriptor desc = SrcReg1; diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index 9345158e9..87fd28a6a 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -26,7 +26,7 @@ // // Authors: Gabe Black -// Copyright (c) 2007 The Hewlett-Packard Development Company +// Copyright (c) 2007-2008 The Hewlett-Packard Development Company // All rights reserved. // // Redistribution and use of this software in source and binary forms, @@ -146,5 +146,6 @@ def operands {{ 'GDTRBase': ('ControlReg', 'uqw', 'MISCREG_TSG_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 205), 'GDTRLimit': ('ControlReg', 'uqw', 'MISCREG_TSG_LIMIT', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 206), 'CSBase': ('ControlReg', 'udw', 'MISCREG_CS_EFF_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 207), + 'TscOp': ('ControlReg', 'udw', 'MISCREG_TSC', (None, None, ['IsSerializeAfter', 'IsSerializing', 'IsNonSpeculative']), 208), 'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 300) }}; diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc index 5d75af0cf..930bf53c7 100644 --- a/src/arch/x86/miscregfile.cc +++ b/src/arch/x86/miscregfile.cc @@ -87,6 +87,7 @@ #include "arch/x86/miscregfile.hh" #include "arch/x86/tlb.hh" +#include "cpu/base.hh" #include "cpu/thread_context.hh" #include "sim/serialize.hh" @@ -178,6 +179,10 @@ MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc) break; } } + switch (miscReg) { + case MISCREG_TSC: + return regVal[MISCREG_TSC] + tc->getCpuPtr()->curCycle(); + } return readRegNoEffect(miscReg); } @@ -377,6 +382,9 @@ void MiscRegFile::setReg(int miscReg, MISCREG_SEG_BASE_BASE)] = val; } break; + case MISCREG_TSC: + regVal[MISCREG_TSC] = val - tc->getCpuPtr()->curCycle(); + return; } setRegNoEffect(miscReg, newVal); } -- cgit v1.2.3 From 254cc076500ab7ee382d76a92db3a5a3c2ec1e62 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:45:22 -0400 Subject: X86: Fix a byte register indexing issue in the sign extending move from memory microcode. --- src/arch/x86/isa/insts/general_purpose/data_transfer/move.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py index 3b8608c48..16196bcc8 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py @@ -1,4 +1,4 @@ -# Copyright (c) 2007 The Hewlett-Packard Development Company +# Copyright (c) 2007-2008 The Hewlett-Packard Development Company # All rights reserved. # # Redistribution and use of this software in source and binary forms, @@ -130,14 +130,14 @@ def macroop MOVSX_B_R_R { }; def macroop MOVSX_B_R_M { - ld reg, seg, sib, disp, dataSize=1 - sexti reg, reg, 7 + ld t1, seg, sib, disp, dataSize=1 + sexti reg, t1, 7 }; def macroop MOVSX_B_R_P { rdip t7 - ld reg, seg, riprel, disp, dataSize=1 - sexti reg, reg, 7 + ld t1, seg, riprel, disp, dataSize=1 + sexti reg, t1, 7 }; def macroop MOVSX_W_R_R { -- cgit v1.2.3 From 16e189fad21cd30a84fa736ac0dd7eb3dc9ba724 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:45:52 -0400 Subject: X86: Bit scan forward/reverse were accidentally transposed. --- .../isa/insts/general_purpose/compare_and_test/bit_scan.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py b/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py index 71059e80d..a18437df3 100644 --- a/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py +++ b/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py @@ -82,7 +82,7 @@ # Authors: Gabe Black microcode = ''' -def macroop BSF_R_R { +def macroop BSR_R_R { # Determine if the input was zero, and also move it to a temp reg. movi t1, t1, t0, dataSize=8 and t1, regm, regm, flags=(ZF,) @@ -131,7 +131,7 @@ end: fault "NoFault" }; -def macroop BSF_R_M { +def macroop BSR_R_M { movi t1, t1, t0, dataSize=8 ld t1, seg, sib, disp @@ -183,7 +183,7 @@ end: fault "NoFault" }; -def macroop BSF_R_P { +def macroop BSR_R_P { rdip t7 movi t1, t1, t0, dataSize=8 @@ -236,7 +236,7 @@ end: fault "NoFault" }; -def macroop BSR_R_R { +def macroop BSF_R_R { # Determine if the input was zero, and also move it to a temp reg. mov t1, t1, t0, dataSize=8 and t1, regm, regm, flags=(ZF,) @@ -282,7 +282,7 @@ end: fault "NoFault" }; -def macroop BSR_R_M { +def macroop BSF_R_M { mov t1, t1, t0, dataSize=8 ld t1, seg, sib, disp @@ -331,7 +331,7 @@ end: fault "NoFault" }; -def macroop BSR_R_P { +def macroop BSF_R_P { rdip t7 mov t1, t1, t0, dataSize=8 -- cgit v1.2.3 From 8e2991b529fd63f4d7c56518ebfbd2424f964172 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:46:04 -0400 Subject: X86: Fix the implementation of BSF. --- .../general_purpose/compare_and_test/bit_scan.py | 90 +++++++++++++--------- 1 file changed, 54 insertions(+), 36 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py b/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py index a18437df3..f2a3db8a3 100644 --- a/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py +++ b/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py @@ -250,33 +250,39 @@ def macroop BSF_R_R { # Bit 6 srli t3, t1, 32, dataSize=8 - andi t3, t3, 32 - or reg, reg, t3 + andi t4, t3, 32, flags=(EZF,) + or reg, reg, t4 + mov t1, t1, t3, flags=(nCEZF,) # Bit 5 srli t3, t1, 16, dataSize=8 - andi t3, t3, 16 - or reg, reg, t3 + andi t4, t3, 16, flags=(EZF,) + or reg, reg, t4 + mov t1, t1, t3, flags=(nCEZF,) # Bit 4 srli t3, t1, 8, dataSize=8 - andi t3, t3, 8 - or reg, reg, t3 + andi t4, t3, 8, flags=(EZF,) + or reg, reg, t4 + mov t1, t1, t3, flags=(nCEZF,) # Bit 3 srli t3, t1, 4, dataSize=8 - andi t3, t3, 4 - or reg, reg, t3 + andi t4, t3, 4, flags=(EZF,) + or reg, reg, t4 + mov t1, t1, t3, flags=(nCEZF,) # Bit 2 srli t3, t1, 2, dataSize=8 - andi t3, t3, 2 - or reg, reg, t3 + andi t4, t3, 2, flags=(EZF,) + or reg, reg, t4 + mov t1, t1, t3, flags=(nCEZF,) # Bit 1 srli t3, t1, 1, dataSize=8 - andi t3, t3, 1 - or reg, reg, t3 + andi t4, t3, 1, flags=(EZF,) + or reg, reg, t4 + mov t1, t1, t3, flags=(nCEZF,) end: fault "NoFault" @@ -299,33 +305,39 @@ def macroop BSF_R_M { # Bit 6 srli t3, t1, 32, dataSize=8 - andi t3, t3, 32 - or reg, reg, t3 + andi t4, t3, 32, flags=(EZF,) + or reg, reg, t4 + mov t1, t1, t3, flags=(nCEZF,) # Bit 5 srli t3, t1, 16, dataSize=8 - andi t3, t3, 16 - or reg, reg, t3 + andi t4, t3, 16, flags=(EZF,) + or reg, reg, t4 + mov t1, t1, t3, flags=(nCEZF,) # Bit 4 srli t3, t1, 8, dataSize=8 - andi t3, t3, 8 - or reg, reg, t3 + andi t4, t3, 8, flags=(EZF,) + or reg, reg, t4 + mov t1, t1, t3, flags=(nCEZF,) # Bit 3 srli t3, t1, 4, dataSize=8 - andi t3, t3, 4 - or reg, reg, t3 + andi t4, t3, 4, flags=(EZF,) + or reg, reg, t4 + mov t1, t1, t3, flags=(nCEZF,) # Bit 2 srli t3, t1, 2, dataSize=8 - andi t3, t3, 2 - or reg, reg, t3 + andi t4, t3, 2, flags=(EZF,) + or reg, reg, t4 + mov t1, t1, t3, flags=(nCEZF,) # Bit 1 srli t3, t1, 1, dataSize=8 - andi t3, t3, 1 - or reg, reg, t3 + andi t4, t3, 1, flags=(EZF,) + or reg, reg, t4 + mov t1, t1, t3, flags=(nCEZF,) end: fault "NoFault" @@ -349,33 +361,39 @@ def macroop BSF_R_P { # Bit 6 srli t3, t1, 32, dataSize=8 - andi t3, t3, 32 - or reg, reg, t3 + andi t4, t3, 32, flags=(EZF,) + or reg, reg, t4 + mov t1, t1, t3, flags=(nCEZF,) # Bit 5 srli t3, t1, 16, dataSize=8 - andi t3, t3, 16 - or reg, reg, t3 + andi t4, t3, 16, flags=(EZF,) + or reg, reg, t4 + mov t1, t1, t3, flags=(nCEZF,) # Bit 4 srli t3, t1, 8, dataSize=8 - andi t3, t3, 8 - or reg, reg, t3 + andi t4, t3, 8, flags=(EZF,) + or reg, reg, t4 + mov t1, t1, t3, flags=(nCEZF,) # Bit 3 srli t3, t1, 4, dataSize=8 - andi t3, t3, 4 - or reg, reg, t3 + andi t4, t3, 4, flags=(EZF,) + or reg, reg, t4 + mov t1, t1, t3, flags=(nCEZF,) # Bit 2 srli t3, t1, 2, dataSize=8 - andi t3, t3, 2 - or reg, reg, t3 + andi t4, t3, 2, flags=(EZF,) + or reg, reg, t4 + mov t1, t1, t3, flags=(nCEZF,) # Bit 1 srli t3, t1, 1, dataSize=8 - andi t3, t3, 1 - or reg, reg, t3 + andi t4, t3, 1, flags=(EZF,) + or reg, reg, t4 + mov t1, t1, t3, flags=(nCEZF,) end: fault "NoFault" -- cgit v1.2.3 From b3e55339f90dbf7f719e8f8348356e1ad03d74bb Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:46:22 -0400 Subject: X86: Remove enforcement of APIC register access alignment. Panic if more than one register is accessed at a time. --- src/arch/x86/mmaped_ipr.hh | 29 ++++++++++++----------------- src/arch/x86/tlb.cc | 15 +++++++++++++-- 2 files changed, 25 insertions(+), 19 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/mmaped_ipr.hh b/src/arch/x86/mmaped_ipr.hh index eda85c084..cf3eba5e9 100644 --- a/src/arch/x86/mmaped_ipr.hh +++ b/src/arch/x86/mmaped_ipr.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 The Hewlett-Packard Development Company + * Copyright (c) 2007-2008 The Hewlett-Packard Development Company * All rights reserved. * * Redistribution and use of this software in source and binary forms, @@ -78,15 +78,12 @@ namespace X86ISA #if !FULL_SYSTEM panic("Shouldn't have a memory mapped register in SE\n"); #else + Addr offset = pkt->getAddr() & mask(3); MiscRegIndex index = (MiscRegIndex)(pkt->getAddr() / sizeof(MiscReg)); - if (index == MISCREG_PCI_CONFIG_ADDRESS || - (index >= MISCREG_APIC_START && - index <= MISCREG_APIC_END)) { - pkt->set((uint32_t)(xc->readMiscReg(pkt->getAddr() / - sizeof(MiscReg)))); - } else { - pkt->set(xc->readMiscReg(pkt->getAddr() / sizeof(MiscReg))); - } + MiscReg data = htog(xc->readMiscReg(index)); + // Make sure we don't trot off the end of data. + assert(offset + pkt->getSize() <= sizeof(MiscReg)); + pkt->setData(((uint8_t *)&data) + offset); #endif return xc->getCpuPtr()->ticks(1); } @@ -97,15 +94,13 @@ namespace X86ISA #if !FULL_SYSTEM panic("Shouldn't have a memory mapped register in SE\n"); #else + Addr offset = pkt->getAddr() & mask(3); MiscRegIndex index = (MiscRegIndex)(pkt->getAddr() / sizeof(MiscReg)); - if (index == MISCREG_PCI_CONFIG_ADDRESS || - (index >= MISCREG_APIC_START && - index <= MISCREG_APIC_END)) { - xc->setMiscReg(index, gtoh(pkt->get())); - } else { - xc->setMiscReg(pkt->getAddr() / sizeof(MiscReg), - gtoh(pkt->get())); - } + MiscReg data = htog(xc->readMiscRegNoEffect(index)); + // Make sure we don't trot off the end of data. + assert(offset + pkt->getSize() <= sizeof(MiscReg)); + pkt->writeData(((uint8_t *)&data) + offset); + xc->setMiscReg(index, gtoh(data)); #endif return xc->getCpuPtr()->ticks(1); } diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 3e720c9ae..cbd59c19e 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 The Hewlett-Packard Development Company + * Copyright (c) 2007-2008 The Hewlett-Packard Development Company * All rights reserved. * * Redistribution and use of this software in source and binary forms, @@ -598,13 +598,24 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) Addr paddr = req->getPaddr(); if (baseAddr <= paddr && baseAddr + (1 << 12) > paddr) { req->setMmapedIpr(true); + // The Intel developer's manuals say the below restrictions apply, + // but the linux kernel, because of a compiler optimization, breaks + // them. + /* // Check alignment if (paddr & ((32/8) - 1)) return new GeneralProtection(0); // Check access size if (req->getSize() != (32/8)) return new GeneralProtection(0); + */ + + //Make sure we're at least only accessing one register. + if ((paddr & ~mask(3)) != ((paddr + req->getSize()) & ~mask(3))) + panic("Accessed more than one register at a time in the APIC!\n"); MiscReg regNum; + Addr offset = paddr & mask(3); + paddr &= ~mask(3); switch (paddr - baseAddr) { case 0x20: @@ -732,7 +743,7 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) return new GeneralProtection(0); break; } - req->setPaddr(regNum * sizeof(MiscReg)); + req->setPaddr(regNum * sizeof(MiscReg) + offset); } #endif return NoFault; -- cgit v1.2.3 From a8e3001df85bc1e435a8abe77141ba0f6c9b7f9e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:47:25 -0400 Subject: X86: Bypass unaligned access support for register addressed MSRs. --- .../isa/insts/general_purpose/input_output/general_io.py | 14 ++++++-------- .../isa/insts/general_purpose/input_output/string_io.py | 14 +++++--------- src/arch/x86/isa/insts/system/msrs.py | 8 ++++---- src/arch/x86/tlb.cc | 3 ++- 4 files changed, 17 insertions(+), 22 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/input_output/general_io.py b/src/arch/x86/isa/insts/general_purpose/input_output/general_io.py index 1986a322e..aba318d73 100644 --- a/src/arch/x86/isa/insts/general_purpose/input_output/general_io.py +++ b/src/arch/x86/isa/insts/general_purpose/input_output/general_io.py @@ -84,25 +84,23 @@ microcode = ''' def macroop IN_R_I { .adjust_imm trimImm(8) - limm t1, "IntAddrPrefixIO", dataSize=8 - ld reg, intseg, [1, t1, t0], imm, addressSize=8 + limm t1, imm, dataSize=asz + ld reg, intseg, [1, t1, t0], "IntAddrPrefixIO << 3", addressSize=4 }; def macroop IN_R_R { - limm t1, "IntAddrPrefixIO", dataSize=8 zexti t2, regm, 15, dataSize=2 - ld reg, intseg, [1, t1, t2], addressSize=8 + ld reg, intseg, [1, t2, t0], "IntAddrPrefixIO << 3", addressSize=4 }; def macroop OUT_I_R { .adjust_imm trimImm(8) - limm t1, "IntAddrPrefixIO", dataSize=8 - st reg, intseg, [1, t1, t0], imm, addressSize=8 + limm t1, imm, dataSize=8 + st reg, intseg, [1, t1, t0], "IntAddrPrefixIO << 3", addressSize=4 }; def macroop OUT_R_R { - limm t1, "IntAddrPrefixIO", dataSize=8 zexti t2, reg, 15, dataSize=2 - st regm, intseg, [1, t1, t2], addressSize=8 + st regm, intseg, [1, t2, t0], "IntAddrPrefixIO << 3", addressSize=4 }; ''' diff --git a/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py b/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py index b44203d9c..1b4e086d2 100644 --- a/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py +++ b/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py @@ -1,4 +1,4 @@ -# Copyright (c) 2007 The Hewlett-Packard Development Company +# Copyright (c) 2007-2008 The Hewlett-Packard Development Company # All rights reserved. # # Redistribution and use of this software in source and binary forms, @@ -61,10 +61,9 @@ def macroop INS_M_R { subi t4, t0, dsz, dataSize=asz mov t3, t3, t4, flags=(nCEZF,), dataSize=asz - limm t1, "IntAddrPrefixIO" zexti t2, reg, 15, dataSize=2 - ld t6, intseg, [1, t1, t2], addressSize=8 + ld t6, intseg, [1, t2, t0], "IntAddrPrefixIO << 3", addressSize=8 st t6, es, [1, t0, rdi] add rdi, rdi, t3, dataSize=asz @@ -77,11 +76,10 @@ def macroop INS_E_M_R { subi t4, t0, dsz, dataSize=asz mov t3, t3, t4, flags=(nCEZF,), dataSize=asz - limm t1, "IntAddrPrefixIO" zexti t2, reg, 15, dataSize=2 topOfLoop: - ld t6, intseg, [1, t1, t2], addressSize=8 + ld t6, intseg, [1, t2, t0], "IntAddrPrefixIO << 3", addressSize=8 st t6, es, [1, t0, rdi] subi rcx, rcx, 1, flags=(EZF,), dataSize=asz @@ -97,11 +95,10 @@ def macroop OUTS_R_M { subi t4, t0, dsz, dataSize=asz mov t3, t3, t4, flags=(nCEZF,), dataSize=asz - limm t1, "IntAddrPrefixIO" zexti t2, reg, 15, dataSize=2 ld t6, ds, [1, t0, rsi] - st t6, intseg, [1, t1, t2], addressSize=8 + st t6, intseg, [1, t2, t0], "IntAddrPrefixIO << 3", addressSize=8 add rsi, rsi, t3, dataSize=asz }; @@ -113,12 +110,11 @@ def macroop OUTS_E_R_M { subi t4, t0, dsz, dataSize=asz mov t3, t3, t4, flags=(nCEZF,), dataSize=asz - limm t1, "IntAddrPrefixIO" zexti t2, reg, 15, dataSize=2 topOfLoop: ld t6, ds, [1, t0, rsi] - st t6, intseg, [1, t1, t2], addressSize=8 + st t6, intseg, [1, t2, t0], "IntAddrPrefixIO << 3", addressSize=8 subi rcx, rcx, 1, flags=(EZF,), dataSize=asz add rsi, rsi, t3, dataSize=asz diff --git a/src/arch/x86/isa/insts/system/msrs.py b/src/arch/x86/isa/insts/system/msrs.py index 461ed1054..f3c867398 100644 --- a/src/arch/x86/isa/insts/system/msrs.py +++ b/src/arch/x86/isa/insts/system/msrs.py @@ -84,8 +84,8 @@ microcode = ''' def macroop RDMSR { - limm t1, "IntAddrPrefixMSR >> 3" - ld t2, intseg, [8, t1, rcx], dataSize=8, addressSize=4 + ld t2, intseg, [8, rcx, t0], "IntAddrPrefixMSR << 3", \ + dataSize=8, addressSize=4 mov rax, rax, t2, dataSize=4 srli t2, t2, 32, dataSize=8 mov rdx, rdx, t2, dataSize=4 @@ -93,11 +93,11 @@ def macroop RDMSR def macroop WRMSR { - limm t1, "IntAddrPrefixMSR >> 3" mov t2, t2, rax, dataSize=4 slli t3, rdx, 32, dataSize=8 or t2, t2, t3, dataSize=8 - st t2, intseg, [8, t1, rcx], dataSize=8, addressSize=4 + st t2, intseg, [8, rcx, t0], "IntAddrPrefixMSR << 3", \ + dataSize=8, addressSize=4 }; def macroop RDTSC diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index cbd59c19e..b6793245e 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -206,10 +206,11 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) // value. if (seg == SEGMENT_REG_MS) { DPRINTF(TLB, "Addresses references internal memory.\n"); - Addr prefix = vaddr & IntAddrPrefixMask; + Addr prefix = (vaddr >> 3) & IntAddrPrefixMask; if (prefix == IntAddrPrefixCPUID) { panic("CPUID memory space not yet implemented!\n"); } else if (prefix == IntAddrPrefixMSR) { + vaddr = vaddr >> 3; req->setMmapedIpr(true); Addr regNum = 0; switch (vaddr & ~IntAddrPrefixMask) { -- cgit v1.2.3 From 8688ef3fe523bf40a0b90d88fb986c25571b298a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:48:02 -0400 Subject: X86: Have all 8 machine check registers since the kernel assumes they're there. --- src/arch/x86/miscregs.hh | 14 +++++++++++++- src/arch/x86/tlb.cc | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/miscregs.hh b/src/arch/x86/miscregs.hh index 15ea0d77b..83ba3c0c5 100644 --- a/src/arch/x86/miscregs.hh +++ b/src/arch/x86/miscregs.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 The Hewlett-Packard Development Company + * Copyright (c) 2007-2008 The Hewlett-Packard Development Company * All rights reserved. * * Redistribution and use of this software in source and binary forms, @@ -183,6 +183,9 @@ namespace X86ISA MISCREG_MC2_CTL, MISCREG_MC3_CTL, MISCREG_MC4_CTL, + MISCREG_MC5_CTL, + MISCREG_MC6_CTL, + MISCREG_MC7_CTL, MISCREG_MC_STATUS_BASE, MISCREG_MC0_STATUS = MISCREG_MC_STATUS_BASE, @@ -190,6 +193,9 @@ namespace X86ISA MISCREG_MC2_STATUS, MISCREG_MC3_STATUS, MISCREG_MC4_STATUS, + MISCREG_MC5_STATUS, + MISCREG_MC6_STATUS, + MISCREG_MC7_STATUS, MISCREG_MC_ADDR_BASE, MISCREG_MC0_ADDR = MISCREG_MC_ADDR_BASE, @@ -197,6 +203,9 @@ namespace X86ISA MISCREG_MC2_ADDR, MISCREG_MC3_ADDR, MISCREG_MC4_ADDR, + MISCREG_MC5_ADDR, + MISCREG_MC6_ADDR, + MISCREG_MC7_ADDR, MISCREG_MC_MISC_BASE, MISCREG_MC0_MISC = MISCREG_MC_MISC_BASE, @@ -204,6 +213,9 @@ namespace X86ISA MISCREG_MC2_MISC, MISCREG_MC3_MISC, MISCREG_MC4_MISC, + MISCREG_MC5_MISC, + MISCREG_MC6_MISC, + MISCREG_MC7_MISC, // Extended feature enable register MISCREG_EFER, diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index b6793245e..f5e214a88 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -358,6 +358,15 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) case 0x410: regNum = MISCREG_MC4_CTL; break; + case 0x414: + regNum = MISCREG_MC5_CTL; + break; + case 0x418: + regNum = MISCREG_MC6_CTL; + break; + case 0x41C: + regNum = MISCREG_MC7_CTL; + break; case 0x401: regNum = MISCREG_MC0_STATUS; break; @@ -373,6 +382,15 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) case 0x411: regNum = MISCREG_MC4_STATUS; break; + case 0x415: + regNum = MISCREG_MC5_STATUS; + break; + case 0x419: + regNum = MISCREG_MC6_STATUS; + break; + case 0x41D: + regNum = MISCREG_MC7_STATUS; + break; case 0x402: regNum = MISCREG_MC0_ADDR; break; @@ -388,6 +406,15 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) case 0x412: regNum = MISCREG_MC4_ADDR; break; + case 0x416: + regNum = MISCREG_MC5_ADDR; + break; + case 0x41A: + regNum = MISCREG_MC6_ADDR; + break; + case 0x41E: + regNum = MISCREG_MC7_ADDR; + break; case 0x403: regNum = MISCREG_MC0_MISC; break; @@ -403,6 +430,15 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) case 0x413: regNum = MISCREG_MC4_MISC; break; + case 0x417: + regNum = MISCREG_MC5_MISC; + break; + case 0x41B: + regNum = MISCREG_MC6_MISC; + break; + case 0x41F: + regNum = MISCREG_MC7_MISC; + break; case 0xC0000080: regNum = MISCREG_EFER; break; -- cgit v1.2.3 From de6eeaaa27543f27386b1d9c6528bd60faf75296 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:48:15 -0400 Subject: X86: Make string instructions work when rcx=0. --- .../isa/insts/general_purpose/input_output/string_io.py | 6 ++++++ .../isa/insts/general_purpose/string/compare_strings.py | 16 +++++++++++++--- .../x86/isa/insts/general_purpose/string/load_string.py | 5 ++++- .../x86/isa/insts/general_purpose/string/move_string.py | 5 ++++- .../x86/isa/insts/general_purpose/string/scan_string.py | 16 +++++++++++++--- .../x86/isa/insts/general_purpose/string/store_string.py | 5 ++++- 6 files changed, 44 insertions(+), 9 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py b/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py index 1b4e086d2..29b722d66 100644 --- a/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py +++ b/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py @@ -70,6 +70,8 @@ def macroop INS_M_R { }; def macroop INS_E_M_R { + and t0, rcx, rcx, flags=(EZF,), dataSize=asz + bri t0, label("end"), flags=(CEZF,) # Find the constant we need to either add or subtract from rdi ruflag t0, 10 movi t3, t3, dsz, flags=(CEZF,), dataSize=asz @@ -85,6 +87,7 @@ topOfLoop: subi rcx, rcx, 1, flags=(EZF,), dataSize=asz add rdi, rdi, t3, dataSize=asz bri t0, label("topOfLoop"), flags=(nCEZF,) +end: fault "NoFault" }; @@ -104,6 +107,8 @@ def macroop OUTS_R_M { }; def macroop OUTS_E_R_M { + and t0, rcx, rcx, flags=(EZF,), dataSize=asz + bri t0, label("end"), flags=(CEZF,) # Find the constant we need to either add or subtract from rdi ruflag t0, 10 movi t3, t3, dsz, flags=(CEZF,), dataSize=asz @@ -119,6 +124,7 @@ topOfLoop: subi rcx, rcx, 1, flags=(EZF,), dataSize=asz add rsi, rsi, t3, dataSize=asz bri t0, label("topOfLoop"), flags=(nCEZF,) +end: fault "NoFault" }; ''' diff --git a/src/arch/x86/isa/insts/general_purpose/string/compare_strings.py b/src/arch/x86/isa/insts/general_purpose/string/compare_strings.py index 71b8511b4..9810fe3c2 100644 --- a/src/arch/x86/isa/insts/general_purpose/string/compare_strings.py +++ b/src/arch/x86/isa/insts/general_purpose/string/compare_strings.py @@ -1,4 +1,4 @@ -# Copyright (c) 2007 The Hewlett-Packard Development Company +# Copyright (c) 2007-2008 The Hewlett-Packard Development Company # All rights reserved. # # Redistribution and use of this software in source and binary forms, @@ -75,12 +75,16 @@ def macroop CMPS_M_M { # def macroop CMPS_E_M_M { + and t0, rcx, rcx, flags=(EZF,), dataSize=asz + bri t0, label("end"), flags=(CEZF,) + # Find the constant we need to either add or subtract from rdi ruflag t0, 10 movi t3, t3, dsz, flags=(CEZF,), dataSize=asz subi t4, t0, dsz, dataSize=asz mov t3, t3, t4, flags=(nCEZF,), dataSize=asz +topOfLoop: ld t1, seg, [1, t0, rsi] ld t2, es, [1, t0, rdi] sub t0, t1, t2, flags=(OF, SF, ZF, AF, PF, CF) @@ -88,17 +92,22 @@ def macroop CMPS_E_M_M { subi rcx, rcx, 1, flags=(EZF,), dataSize=asz add rdi, rdi, t3, dataSize=asz add rsi, rsi, t3, dataSize=asz - bri t0, 4, flags=(CSTRZnEZF,) + bri t0, label("topOfLoop"), flags=(CSTRZnEZF,) +end: fault "NoFault" }; def macroop CMPS_N_M_M { + and t0, rcx, rcx, flags=(EZF,), dataSize=asz + bri t0, label("end"), flags=(CEZF,) + # Find the constant we need to either add or subtract from rdi ruflag t0, 10 movi t3, t3, dsz, flags=(CEZF,), dataSize=asz subi t4, t0, dsz, dataSize=asz mov t3, t3, t4, flags=(nCEZF,), dataSize=asz +topOfLoop: ld t1, seg, [1, t0, rsi] ld t2, es, [1, t0, rdi] sub t0, t1, t2, flags=(OF, SF, ZF, AF, PF, CF) @@ -106,7 +115,8 @@ def macroop CMPS_N_M_M { subi rcx, rcx, 1, flags=(EZF,), dataSize=asz add rdi, rdi, t3, dataSize=asz add rsi, rsi, t3, dataSize=asz - bri t0, 4, flags=(CSTRnZnEZF,) + bri t0, label("topOfLoop"), flags=(CSTRnZnEZF,) +end: fault "NoFault" }; ''' diff --git a/src/arch/x86/isa/insts/general_purpose/string/load_string.py b/src/arch/x86/isa/insts/general_purpose/string/load_string.py index 61525c2f2..8cf07fea6 100644 --- a/src/arch/x86/isa/insts/general_purpose/string/load_string.py +++ b/src/arch/x86/isa/insts/general_purpose/string/load_string.py @@ -1,4 +1,4 @@ -# Copyright (c) 2007 The Hewlett-Packard Development Company +# Copyright (c) 2007-2008 The Hewlett-Packard Development Company # All rights reserved. # # Redistribution and use of this software in source and binary forms, @@ -67,6 +67,8 @@ def macroop LODS_M { }; def macroop LODS_E_M { + and t0, rcx, rcx, flags=(EZF,), dataSize=asz + bri t0, label("end"), flags=(CEZF,) # Find the constant we need to either add or subtract from rdi ruflag t0, 10 movi t3, t3, dsz, flags=(CEZF,), dataSize=asz @@ -79,6 +81,7 @@ topOfLoop: subi rcx, rcx, 1, flags=(EZF,), dataSize=asz add rdi, rdi, t3, dataSize=asz bri t0, label("topOfLoop"), flags=(nCEZF,) +end: fault "NoFault" }; ''' diff --git a/src/arch/x86/isa/insts/general_purpose/string/move_string.py b/src/arch/x86/isa/insts/general_purpose/string/move_string.py index b64acfdc2..1d7dd75ad 100644 --- a/src/arch/x86/isa/insts/general_purpose/string/move_string.py +++ b/src/arch/x86/isa/insts/general_purpose/string/move_string.py @@ -1,4 +1,4 @@ -# Copyright (c) 2007 The Hewlett-Packard Development Company +# Copyright (c) 2007-2008 The Hewlett-Packard Development Company # All rights reserved. # # Redistribution and use of this software in source and binary forms, @@ -69,6 +69,8 @@ def macroop MOVS_M_M { }; def macroop MOVS_E_M_M { + and t0, rcx, rcx, flags=(EZF,), dataSize=asz + bri t0, label("end"), flags=(CEZF,) # Find the constant we need to either add or subtract from rdi ruflag t0, 10 movi t3, t3, dsz, flags=(CEZF,), dataSize=asz @@ -83,6 +85,7 @@ topOfLoop: add rdi, rdi, t3, dataSize=asz add rsi, rsi, t3, dataSize=asz bri t0, label("topOfLoop"), flags=(nCEZF,) +end: fault "NoFault" }; ''' diff --git a/src/arch/x86/isa/insts/general_purpose/string/scan_string.py b/src/arch/x86/isa/insts/general_purpose/string/scan_string.py index b038cc00a..b37e367be 100644 --- a/src/arch/x86/isa/insts/general_purpose/string/scan_string.py +++ b/src/arch/x86/isa/insts/general_purpose/string/scan_string.py @@ -1,4 +1,4 @@ -# Copyright (c) 2007 The Hewlett-Packard Development Company +# Copyright (c) 2007-2008 The Hewlett-Packard Development Company # All rights reserved. # # Redistribution and use of this software in source and binary forms, @@ -73,34 +73,44 @@ def macroop SCAS_M { # def macroop SCAS_E_M { + and t0, rcx, rcx, flags=(EZF,), dataSize=asz + bri t0, label("end"), flags=(CEZF,) + # Find the constant we need to either add or subtract from rdi ruflag t0, 10 movi t2, t2, dsz, flags=(CEZF,), dataSize=asz subi t3, t0, dsz, dataSize=asz mov t2, t2, t3, flags=(nCEZF,), dataSize=asz +topOfLoop: ld t1, es, [1, t0, rdi] sub t0, t1, rax, flags=(OF, SF, ZF, AF, PF, CF) subi rcx, rcx, 1, flags=(EZF,), dataSize=asz add rdi, rdi, t2, dataSize=asz - bri t0, 4, flags=(CSTRZnEZF,) + bri t0, label("topOfLoop"), flags=(CSTRZnEZF,) +end: fault "NoFault" }; def macroop SCAS_N_M { + and t0, rcx, rcx, flags=(EZF,), dataSize=asz + bri t0, label("end"), flags=(CEZF,) + # Find the constant we need to either add or subtract from rdi ruflag t0, 10 movi t2, t2, dsz, flags=(CEZF,), dataSize=asz subi t3, t0, dsz, dataSize=asz mov t2, t2, t3, flags=(nCEZF,), dataSize=asz +topOfLoop: ld t1, es, [1, t0, rdi] sub t0, t1, rax, flags=(OF, SF, ZF, AF, PF, CF) subi rcx, rcx, 1, flags=(EZF,), dataSize=asz add rdi, rdi, t2, dataSize=asz - bri t0, 4, flags=(CSTRnZnEZF,) + bri t0, label("topOfLoop"), flags=(CSTRnZnEZF,) +end: fault "NoFault" }; diff --git a/src/arch/x86/isa/insts/general_purpose/string/store_string.py b/src/arch/x86/isa/insts/general_purpose/string/store_string.py index a8d558929..b52b1f1fb 100644 --- a/src/arch/x86/isa/insts/general_purpose/string/store_string.py +++ b/src/arch/x86/isa/insts/general_purpose/string/store_string.py @@ -1,4 +1,4 @@ -# Copyright (c) 2007 The Hewlett-Packard Development Company +# Copyright (c) 2007-2008 The Hewlett-Packard Development Company # All rights reserved. # # Redistribution and use of this software in source and binary forms, @@ -67,6 +67,8 @@ def macroop STOS_M { }; def macroop STOS_E_M { + and t0, rcx, rcx, flags=(EZF,), dataSize=asz + bri t0, label("end"), flags=(CEZF,) # Find the constant we need to either add or subtract from rdi ruflag t0, 10 movi t3, t3, dsz, flags=(CEZF,), dataSize=asz @@ -79,6 +81,7 @@ topOfLoop: subi rcx, rcx, 1, flags=(EZF,), dataSize=asz add rdi, rdi, t3, dataSize=asz bri t0, label("topOfLoop"), flags=(nCEZF,) +end: fault "NoFault" }; ''' -- cgit v1.2.3 From dfc2d44ea346f9e64059f0738c87519adf3fe4d7 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:48:46 -0400 Subject: X86: Flesh out 3dnow instruction decoding a bit and grab the byte immediate. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 6 +++--- src/arch/x86/predecoder_tables.cc | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index e2d968c17..5ada6fd4f 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -181,9 +181,9 @@ 0x2: Inst::UD2(); 0x3: Inst::UD2(); 0x4: Inst::UD2(); - 0x5: threednow(); - 0x6: threednow(); - 0x7: threednow(); + 0x5: prefetch(); + 0x6: FailUnimpl::femms(); + 0x7: FailUnimpl::threednow(); } 0x02: decode LEGACY_DECODEVAL { // no prefix diff --git a/src/arch/x86/predecoder_tables.cc b/src/arch/x86/predecoder_tables.cc index a8c719054..f8aff39f1 100644 --- a/src/arch/x86/predecoder_tables.cc +++ b/src/arch/x86/predecoder_tables.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 The Hewlett-Packard Development Company + * Copyright (c) 2007-2008 The Hewlett-Packard Development Company * All rights reserved. * * Redistribution and use of this software in source and binary forms, @@ -201,7 +201,7 @@ namespace X86ISA //For two byte instructions { //LSB // MSB 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F -/* 0 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , +/* 0 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , BY , /* 0 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* 2 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* 3 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -- cgit v1.2.3 From 6106b05b6e9cabe3a06da8407818479a5781d249 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:48:58 -0400 Subject: X86: Redo BSF. --- .../general_purpose/compare_and_test/bit_scan.py | 113 ++++++++++----------- 1 file changed, 55 insertions(+), 58 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py b/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py index f2a3db8a3..bfc0af900 100644 --- a/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py +++ b/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py @@ -125,7 +125,6 @@ def macroop BSR_R_R { srli t3, t1, 1, dataSize=8, flags=(EZF,) ori t4, reg, 0x1 mov reg, reg, t4, flags=(nCEZF,) - mov t1, t1, t3, flags=(nCEZF,) end: fault "NoFault" @@ -177,7 +176,6 @@ def macroop BSR_R_M { srli t3, t1, 1, dataSize=8, flags=(EZF,) ori t4, reg, 0x1 mov reg, reg, t4, flags=(nCEZF,) - mov t1, t1, t3, flags=(nCEZF,) end: fault "NoFault" @@ -230,7 +228,6 @@ def macroop BSR_R_P { srli t3, t1, 1, dataSize=8, flags=(EZF,) ori t4, reg, 0x1 mov reg, reg, t4, flags=(nCEZF,) - mov t1, t1, t3, flags=(nCEZF,) end: fault "NoFault" @@ -248,41 +245,41 @@ def macroop BSF_R_R { subi t2, t1, 1 xor t1, t2, t1 + # Bit 6 - srli t3, t1, 32, dataSize=8 - andi t4, t3, 32, flags=(EZF,) - or reg, reg, t4 + srli t3, t1, 32, dataSize=8, flags=(EZF,) + ori t4, reg, 32 + mov reg, reg, t4, flags=(nCEZF,) mov t1, t1, t3, flags=(nCEZF,) # Bit 5 - srli t3, t1, 16, dataSize=8 - andi t4, t3, 16, flags=(EZF,) - or reg, reg, t4 + srli t3, t1, 16, dataSize=8, flags=(EZF,) + ori t4, reg, 16 + mov reg, reg, t4, flags=(nCEZF,) mov t1, t1, t3, flags=(nCEZF,) # Bit 4 - srli t3, t1, 8, dataSize=8 - andi t4, t3, 8, flags=(EZF,) - or reg, reg, t4 + srli t3, t1, 8, dataSize=8, flags=(EZF,) + ori t4, reg, 8 + mov reg, reg, t4, flags=(nCEZF,) mov t1, t1, t3, flags=(nCEZF,) # Bit 3 - srli t3, t1, 4, dataSize=8 - andi t4, t3, 4, flags=(EZF,) - or reg, reg, t4 + srli t3, t1, 4, dataSize=8, flags=(EZF,) + ori t4, reg, 4 + mov reg, reg, t4, flags=(nCEZF,) mov t1, t1, t3, flags=(nCEZF,) # Bit 2 - srli t3, t1, 2, dataSize=8 - andi t4, t3, 2, flags=(EZF,) - or reg, reg, t4 + srli t3, t1, 2, dataSize=8, flags=(EZF,) + ori t4, reg, 2 + mov reg, reg, t4, flags=(nCEZF,) mov t1, t1, t3, flags=(nCEZF,) # Bit 1 - srli t3, t1, 1, dataSize=8 - andi t4, t3, 1, flags=(EZF,) - or reg, reg, t4 - mov t1, t1, t3, flags=(nCEZF,) + srli t3, t1, 1, dataSize=8, flags=(EZF,) + ori t4, reg, 1 + mov reg, reg, t4, flags=(nCEZF,) end: fault "NoFault" @@ -304,39 +301,39 @@ def macroop BSF_R_M { xor t1, t2, t1 # Bit 6 - srli t3, t1, 32, dataSize=8 - andi t4, t3, 32, flags=(EZF,) - or reg, reg, t4 + srli t3, t1, 32, dataSize=8, flags=(EZF,) + ori t4, reg, 32 + mov reg, reg, t4, flags=(nCEZF,) mov t1, t1, t3, flags=(nCEZF,) # Bit 5 - srli t3, t1, 16, dataSize=8 - andi t4, t3, 16, flags=(EZF,) - or reg, reg, t4 + srli t3, t1, 16, dataSize=8, flags=(EZF,) + ori t4, reg, 16 + mov reg, reg, t4, flags=(nCEZF,) mov t1, t1, t3, flags=(nCEZF,) # Bit 4 - srli t3, t1, 8, dataSize=8 - andi t4, t3, 8, flags=(EZF,) - or reg, reg, t4 + srli t3, t1, 8, dataSize=8, flags=(EZF,) + ori t4, reg, 8 + mov reg, reg, t4, flags=(nCEZF,) mov t1, t1, t3, flags=(nCEZF,) # Bit 3 - srli t3, t1, 4, dataSize=8 - andi t4, t3, 4, flags=(EZF,) - or reg, reg, t4 + srli t3, t1, 4, dataSize=8, flags=(EZF,) + ori t4, reg, 4 + mov reg, reg, t4, flags=(nCEZF,) mov t1, t1, t3, flags=(nCEZF,) # Bit 2 - srli t3, t1, 2, dataSize=8 - andi t4, t3, 2, flags=(EZF,) - or reg, reg, t4 + srli t3, t1, 2, dataSize=8, flags=(EZF,) + ori t4, reg, 2 + mov reg, reg, t4, flags=(nCEZF,) mov t1, t1, t3, flags=(nCEZF,) # Bit 1 - srli t3, t1, 1, dataSize=8 - andi t4, t3, 1, flags=(EZF,) - or reg, reg, t4 + srli t3, t1, 1, dataSize=8, flags=(EZF,) + ori t4, reg, 1 + mov reg, reg, t4, flags=(nCEZF,) mov t1, t1, t3, flags=(nCEZF,) end: @@ -360,39 +357,39 @@ def macroop BSF_R_P { xor t1, t2, t1 # Bit 6 - srli t3, t1, 32, dataSize=8 - andi t4, t3, 32, flags=(EZF,) - or reg, reg, t4 + srli t3, t1, 32, dataSize=8, flags=(EZF,) + ori t4, reg, 32 + mov reg, reg, t4, flags=(nCEZF,) mov t1, t1, t3, flags=(nCEZF,) # Bit 5 - srli t3, t1, 16, dataSize=8 - andi t4, t3, 16, flags=(EZF,) - or reg, reg, t4 + srli t3, t1, 16, dataSize=8, flags=(EZF,) + ori t4, reg, 16 + mov reg, reg, t4, flags=(nCEZF,) mov t1, t1, t3, flags=(nCEZF,) # Bit 4 - srli t3, t1, 8, dataSize=8 - andi t4, t3, 8, flags=(EZF,) - or reg, reg, t4 + srli t3, t1, 8, dataSize=8, flags=(EZF,) + ori t4, reg, 8 + mov reg, reg, t4, flags=(nCEZF,) mov t1, t1, t3, flags=(nCEZF,) # Bit 3 - srli t3, t1, 4, dataSize=8 - andi t4, t3, 4, flags=(EZF,) - or reg, reg, t4 + srli t3, t1, 4, dataSize=8, flags=(EZF,) + ori t4, reg, 4 + mov reg, reg, t4, flags=(nCEZF,) mov t1, t1, t3, flags=(nCEZF,) # Bit 2 - srli t3, t1, 2, dataSize=8 - andi t4, t3, 2, flags=(EZF,) - or reg, reg, t4 + srli t3, t1, 2, dataSize=8, flags=(EZF,) + ori t4, reg, 2 + mov reg, reg, t4, flags=(nCEZF,) mov t1, t1, t3, flags=(nCEZF,) # Bit 1 - srli t3, t1, 1, dataSize=8 - andi t4, t3, 1, flags=(EZF,) - or reg, reg, t4 + srli t3, t1, 1, dataSize=8, flags=(EZF,) + ori t4, reg, 1 + mov reg, reg, t4, flags=(nCEZF,) mov t1, t1, t3, flags=(nCEZF,) end: -- cgit v1.2.3 From bbc1f394ffd9d3add42494ad852ac29c3e5e7711 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:49:16 -0400 Subject: X86: Truncate descriptors to 16 bits. --- src/arch/x86/isa/microops/regop.isa | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 03a7515ed..35f1fef02 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -988,20 +988,20 @@ let {{ class Chks(SegOp): code = ''' - // The selector is in source 1. + // The selector is in source 1 and can be at most 16 bits. SegSelector selector = psrc1; // Compute the address of the descriptor and set DestReg to it. if (selector.ti) { // A descriptor in the LDT - Addr target = (selector.esi << 3) + LDTRBase; - if (!LDTRSel || (selector.esi << 3) + dataSize > LDTRLimit) + Addr target = (selector.si << 3) + LDTRBase; + if (!LDTRSel || (selector.si << 3) + dataSize > LDTRLimit) fault = new GeneralProtection(selector & mask(16)); DestReg = target; } else { // A descriptor in the GDT - Addr target = (selector.esi << 3) + GDTRBase; - if ((selector.esi << 3) + dataSize > GDTRLimit) + Addr target = (selector.si << 3) + GDTRBase; + if ((selector.si << 3) + dataSize > GDTRLimit) fault = new GeneralProtection(selector & mask(16)); DestReg = target; } @@ -1009,7 +1009,7 @@ let {{ flag_code = ''' // Check for a NULL selector and set ZF,EZF appropriately. ccFlagBits = ccFlagBits & ~(ext & (ZFBit | EZFBit)); - if (!selector.esi && !selector.ti) + if (!selector.si && !selector.ti) ccFlagBits = ccFlagBits | (ext & (ZFBit | EZFBit)); ''' -- cgit v1.2.3 From 2bb8933f789d65f47a322e1384eb2e500699bf14 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:49:25 -0400 Subject: X86: Add microops which panic, fatal, warn, and warn_once. --- src/arch/x86/isa/includes.isa | 3 +- src/arch/x86/isa/microops/debug.isa | 229 +++++++++++++++++++++++++++++++++ src/arch/x86/isa/microops/microops.isa | 5 +- 3 files changed, 235 insertions(+), 2 deletions(-) create mode 100644 src/arch/x86/isa/microops/debug.isa (limited to 'src/arch') diff --git a/src/arch/x86/isa/includes.isa b/src/arch/x86/isa/includes.isa index 6724ea9b0..6d0fe6d86 100644 --- a/src/arch/x86/isa/includes.isa +++ b/src/arch/x86/isa/includes.isa @@ -26,7 +26,7 @@ // // Authors: Gabe Black -// Copyright (c) 2007 The Hewlett-Packard Development Company +// Copyright (c) 2007-2008 The Hewlett-Packard Development Company // All rights reserved. // // Redistribution and use of this software in source and binary forms, @@ -117,6 +117,7 @@ output decoder {{ #include "arch/x86/segmentregs.hh" #include "base/cprintf.hh" #include "base/loader/symtab.hh" +#include "base/misc.hh" #include "cpu/thread_context.hh" // for Jump::branchTarget() #include "mem/packet.hh" diff --git a/src/arch/x86/isa/microops/debug.isa b/src/arch/x86/isa/microops/debug.isa new file mode 100644 index 000000000..7456b0d4e --- /dev/null +++ b/src/arch/x86/isa/microops/debug.isa @@ -0,0 +1,229 @@ +// Copyright (c) 2008 The Hewlett-Packard Development Company +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the +// following conditions are met: +// +// The software must be used only for Non-Commercial Use which means any +// use which is NOT directed to receiving any direct monetary +// compensation for, or commercial advantage from such use. Illustrative +// examples of non-commercial use are academic research, personal study, +// teaching, education and corporate research & development. +// Illustrative examples of commercial use are distributing products for +// commercial advantage and providing services using the software for +// commercial advantage. +// +// If you wish to use this software or functionality therein that may be +// covered by patents for commercial use, please contact: +// Director of Intellectual Property Licensing +// Office of Strategy and Technology +// Hewlett-Packard Company +// 1501 Page Mill Road +// Palo Alto, California 94304 +// +// Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. Redistributions +// in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or +// other materials provided with the distribution. Neither the name of +// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. No right of +// sublicense is granted herewith. Derivatives of the software and +// output created using the software may be prepared, but only for +// Non-Commercial Uses. Derivatives of the software may be shared with +// others provided: (i) the others agree to abide by the list of +// conditions herein which includes the Non-Commercial Use restrictions; +// and (ii) such Derivatives of the software include the above copyright +// notice to acknowledge the contribution from this software where +// applicable, this list of conditions and the disclaimer below. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Gabe Black + +////////////////////////////////////////////////////////////////////////// +// +// Debug Microops +// +////////////////////////////////////////////////////////////////////////// + +output header {{ + class MicroDebugBase : public X86ISA::X86MicroopBase + { + protected: + std::string message; + uint8_t cc; + + public: + MicroDebugBase(ExtMachInst _machInst, const char * mnem, + const char * instMnem, + bool isMicro, bool isDelayed, bool isFirst, bool isLast, + std::string _message, uint8_t _cc); + + MicroDebugBase(ExtMachInst _machInst, const char * mnem, + const char * instMnem, std::string _message, uint8_t _cc); + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + }; +}}; + +def template MicroDebugDeclare {{ + class %(class_name)s : public %(base_class)s + { + private: + void buildMe(); + public: + %(class_name)s(ExtMachInst _machInst, const char * instMnem, + bool isMicro, bool isDelayed, bool isFirst, bool isLast, + std::string _message, uint8_t _cc); + + %(class_name)s(ExtMachInst _machInst, const char * instMnem, + std::string _message, uint8_t _cc); + + %(BasicExecDeclare)s + }; +}}; + +def template MicroDebugExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + %(op_decl)s + %(op_rd)s + if (%(cond_test)s) { + %(func)s(message + "\n"); + } + return NoFault; + } +}}; + +output decoder {{ + inline MicroDebugBase::MicroDebugBase( + ExtMachInst machInst, const char * mnem, const char * instMnem, + std::string _message, uint8_t _cc) : + X86MicroopBase(machInst, mnem, instMnem, + false, false, false, false, No_OpClass), + message(_message), cc(_cc) + { + } + + inline MicroDebugBase::MicroDebugBase( + ExtMachInst machInst, const char * mnem, const char * instMnem, + bool isMicro, bool isDelayed, bool isFirst, bool isLast, + std::string _message, uint8_t _cc) : + X86MicroopBase(machInst, mnem, instMnem, + isMicro, isDelayed, isFirst, isLast, No_OpClass), + message(_message), cc(_cc) + { + } +}}; + +def template MicroDebugConstructor {{ + + inline void %(class_name)s::buildMe() + { + %(constructor)s; + } + + inline %(class_name)s::%(class_name)s( + ExtMachInst machInst, const char * instMnem, + std::string _message, uint8_t _cc) : + %(base_class)s(machInst, "%(func)s", instMnem, _message, _cc) + { + buildMe(); + } + + inline %(class_name)s::%(class_name)s( + ExtMachInst machInst, const char * instMnem, + bool isMicro, bool isDelayed, bool isFirst, bool isLast, + std::string _message, uint8_t _cc) : + %(base_class)s(machInst, "%(func)s", instMnem, + isMicro, isDelayed, isFirst, isLast, _message, _cc) + { + buildMe(); + } +}}; + +output decoder {{ + std::string MicroDebugBase::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream response; + + printMnemonic(response, instMnem, mnemonic); + response << "\"" << message << "\""; + + return response.str(); + } +}}; + +let {{ + class MicroDebug(X86Microop): + def __init__(self, message, flags=None): + self.message = message + if flags: + if not isinstance(flags, (list, tuple)): + raise Exception, "flags must be a list or tuple of flags" + self.cond = " | ".join(flags) + self.className += "Flags" + else: + self.cond = "0" + + def getAllocator(self, *microFlags): + allocator = '''new %(class_name)s(machInst, mnemonic + %(flags)s, "%(message)s", %(cc)s)''' % { + "class_name" : self.className, + "flags" : self.microFlagsText(microFlags), + "message" : self.message, + "cc" : self.cond} + return allocator + + exec_output = "" + header_output = "" + decoder_output = "" + + def buildDebugMicro(func): + global exec_output, header_output, decoder_output + + iop = InstObjParams(func, "Micro%sFlags" % func.capitalize(), + "MicroDebugBase", + {"code": "", + "func": func, + "cond_test": "checkCondition(ccFlagBits, cc)"}) + exec_output += MicroDebugExecute.subst(iop) + header_output += MicroDebugDeclare.subst(iop) + decoder_output += MicroDebugConstructor.subst(iop) + + iop = InstObjParams(func, "Micro%s" % func.capitalize(), + "MicroDebugBase", + {"code": "", + "func": func, + "cond_test": "true"}) + exec_output += MicroDebugExecute.subst(iop) + header_output += MicroDebugDeclare.subst(iop) + decoder_output += MicroDebugConstructor.subst(iop) + + class MicroDebugChild(MicroDebug): + className = "Micro%s" % func.capitalize() + + global microopClasses + microopClasses[func] = MicroDebugChild + + buildDebugMicro("panic") + buildDebugMicro("fatal") + buildDebugMicro("warn") + buildDebugMicro("warn_once") +}}; diff --git a/src/arch/x86/isa/microops/microops.isa b/src/arch/x86/isa/microops/microops.isa index 53f34d3f2..1c9e8358a 100644 --- a/src/arch/x86/isa/microops/microops.isa +++ b/src/arch/x86/isa/microops/microops.isa @@ -1,4 +1,4 @@ -// Copyright (c) 2007 The Hewlett-Packard Development Company +// Copyright (c) 2007-2008 The Hewlett-Packard Development Company // All rights reserved. // // Redistribution and use of this software in source and binary forms, @@ -70,3 +70,6 @@ //Miscellaneous microop definitions ##include "specop.isa" + +//Microops for printing out debug messages through M5 +##include "debug.isa" -- cgit v1.2.3 From e0c20386ac0f8f54db2e8947793b4c2debabcefc Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:49:50 -0400 Subject: X86: Add microops and supporting code to manipulate the whole rflags register. --- .../insts/general_purpose/flags/push_and_pop.py | 8 +++---- src/arch/x86/isa/microasm.isa | 5 ++-- src/arch/x86/isa/microops/regop.isa | 27 ++++++++++++++++++++++ src/arch/x86/isa/operands.isa | 7 ++++-- src/arch/x86/miscregs.hh | 12 ++++++++++ 5 files changed, 50 insertions(+), 9 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/flags/push_and_pop.py b/src/arch/x86/isa/insts/general_purpose/flags/push_and_pop.py index fe60350c1..5937ac074 100644 --- a/src/arch/x86/isa/insts/general_purpose/flags/push_and_pop.py +++ b/src/arch/x86/isa/insts/general_purpose/flags/push_and_pop.py @@ -1,4 +1,4 @@ -# Copyright (c) 2007 The Hewlett-Packard Development Company +# Copyright (c) 2007-2008 The Hewlett-Packard Development Company # All rights reserved. # # Redistribution and use of this software in source and binary forms, @@ -57,8 +57,7 @@ microcode = ''' def macroop PUSHF { .adjust_env oszIn64Override - # This should really read the whole flags register, not just user flags. - ruflags t1 + rflags t1 stupd t1, ss, [1, t0, rsp], "-env.dataSize" }; @@ -67,7 +66,6 @@ def macroop POPF { ld t1, ss, [1, t0, rsp] addi rsp, rsp, dsz - # This should really write the whole flags register, not just user flags. - wruflags t1, t0 + wrflags t1, t0 }; ''' diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index 78ae34f52..18abdf09b 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -1,6 +1,6 @@ // -*- mode:c++ -*- -// Copyright (c) 2007 The Hewlett-Packard Development Company +// Copyright (c) 2007-2008 The Hewlett-Packard Development Company // All rights reserved. // // Redistribution and use of this software in source and binary forms, @@ -135,7 +135,8 @@ let {{ for reg in range(15): assembler.symbols["cr%d" % reg] = "MISCREG_CR%d" % reg - for flag in ('CF', 'PF', 'ECF', 'AF', 'EZF', 'ZF', 'SF', 'OF'): + for flag in ('CF', 'PF', 'ECF', 'AF', 'EZF', 'ZF', 'SF', 'OF', \ + 'TF', 'IF', 'NT', 'RF', 'VM', 'AC', 'VIF', 'VIP', 'ID'): assembler.symbols[flag] = flag + "Bit" for cond in ('True', 'False', 'ECF', 'EZF', 'SZnZF', diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 35f1fef02..0187567e9 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -845,12 +845,25 @@ let {{ class Wruflags(WrRegOp): code = 'ccFlagBits = psrc1 ^ op2' + class Wrflags(WrRegOp): + code = ''' + MiscReg newFlags = psrc1 ^ op2; + MiscReg userFlagMask = 0xDD5; + // Get only the user flags + ccFlagBits = newFlags & userFlagMask; + // Get everything else + nccFlagBits = newFlags & ~userFlagMask; + ''' + class Rdip(RdRegOp): code = 'DestReg = RIP - CSBase' class Ruflags(RdRegOp): code = 'DestReg = ccFlagBits' + class Rflags(RdRegOp): + code = 'DestReg = ccFlagBits | nccFlagBits' + class Ruflag(RegOp): code = ''' int flag = bits(ccFlagBits, imm8); @@ -863,6 +876,20 @@ let {{ super(Ruflag, self).__init__(dest, \ "NUM_INTREGS", imm, flags, dataSize) + class Rflag(RegOp): + code = ''' + MiscReg flagMask = 0x3F7FDD5; + MiscReg flags = (nccFlagBits | ccFlagBits) & flagMask; + int flag = bits(flags, imm8); + DestReg = merge(DestReg, flag, dataSize); + ccFlagBits = (flag == 0) ? (ccFlagBits | EZFBit) : + (ccFlagBits & ~EZFBit); + ''' + def __init__(self, dest, imm, flags=None, \ + dataSize="env.dataSize"): + super(Rflag, self).__init__(dest, \ + "NUM_INTREGS", imm, flags, dataSize) + class Sext(RegOp): code = ''' IntReg val = psrc1; diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index 87fd28a6a..b48e8759f 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -117,10 +117,13 @@ def operands {{ 'RIP': ('NPC', 'uqw', None, (None, None, 'IsControl'), 50), 'uIP': ('UPC', 'uqw', None, (None, None, 'IsControl'), 51), 'nuIP': ('NUPC', 'uqw', None, (None, None, 'IsControl'), 52), + # This holds the condition code portion of the flag register. The + # nccFlagBits version holds the rest. 'ccFlagBits': ('IntReg', 'uqw', 'INTREG_PSEUDO(0)', None, 60), - # The TOP register should needs to be more protected so that later + # These register should needs to be more protected so that later # instructions don't map their indexes with an old value. - 'TOP': ('ControlReg', 'ub', 'MISCREG_X87_TOP', None, 61), + 'nccFlagBits': ('ControlReg', 'uqw', 'MISCREG_RFLAGS', None, 61), + 'TOP': ('ControlReg', 'ub', 'MISCREG_X87_TOP', None, 62), # The segment base as used by memory instructions. 'SegBase': ('ControlReg', 'uqw', 'MISCREG_SEG_EFF_BASE(segment)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 70), diff --git a/src/arch/x86/miscregs.hh b/src/arch/x86/miscregs.hh index 83ba3c0c5..90f1d9fda 100644 --- a/src/arch/x86/miscregs.hh +++ b/src/arch/x86/miscregs.hh @@ -82,6 +82,18 @@ namespace X86ISA OFBit = 1 << 11 }; + enum RFLAGBit { + TFBit = 1 << 8, + IFBit = 1 << 9, + NTBit = 1 << 14, + RFBit = 1 << 16, + VMBit = 1 << 17, + ACBit = 1 << 18, + VIFBit = 1 << 19, + VIPBit = 1 << 20, + IDBit = 1 << 21 + }; + enum MiscRegIndex { // Control registers -- cgit v1.2.3 From 6bd9cf3594b0150c8cb39a23ca2cfb465b6e09bb Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:50:05 -0400 Subject: X86: Add a microop to read a segments attribute register. --- src/arch/x86/isa/microops/regop.isa | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 0187567e9..48aecf138 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -1008,6 +1008,11 @@ let {{ DestReg = SegLimitSrc1; ''' + class RdAttr(SegOp): + code = ''' + DestReg = SegAttrSrc1; + ''' + class Rdsel(SegOp): code = ''' DestReg = SegSelSrc1; -- cgit v1.2.3 From fa7c81c6df5fdc1a17ffebbf431cb57ac84d79d0 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:50:10 -0400 Subject: X86: Change what the microop chks does. Instead of computing the segment descriptor address, this now checks if a selector value/descriptor are legal for a particular purpose. --- src/arch/x86/isa/microasm.isa | 5 +++++ src/arch/x86/isa/microops/regop.isa | 42 ++++++++++++++++++++++++++++++++++++- src/arch/x86/isa/operands.isa | 3 ++- 3 files changed, 48 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index 18abdf09b..735a7722c 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -81,6 +81,11 @@ let {{ for letter in ("C", "D", "E", "F", "G", "S"): assembler.symbols["%ss" % letter.lower()] = "SEGMENT_REG_%sS" % letter + # Add in symbols for the various checks of segment selectors. + for check in ("NoCheck", "CSCheck", "CallGateCheck", + "SSCheck", "IretCheck", "IntCSCheck"): + assembler.symbols[check] = "Seg%s" % check + for reg in ("TR", "IDTR"): assembler.symbols[reg.lower()] = "SYS_SEGMENT_REG_%s" % reg diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 48aecf138..6bd26608e 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -231,6 +231,11 @@ output header {{ void divide(uint64_t dividend, uint64_t divisor, uint64_t "ient, uint64_t &remainder); + + enum SegmentSelectorCheck { + SegNoCheck, SegCSCheck, SegCallGateCheck, + SegSSCheck, SegIretCheck, SegIntCSCheck + }; }}; output decoder {{ @@ -1018,11 +1023,46 @@ let {{ DestReg = SegSelSrc1; ''' - class Chks(SegOp): + class Chks(RegOp): + def __init__(self, dest, src1, src2=0, + flags=None, dataSize="env.dataSize"): + super(Chks, self).__init__(dest, + src1, src2, flags, dataSize) code = ''' // The selector is in source 1 and can be at most 16 bits. SegSelector selector = psrc1; + switch (imm8) + { + case SegNoCheck: + break; + case SegCSCheck: + panic("CS checks for far calls/jumps not implemented.\\n"); + break; + case SegCallGateCheck: + panic("CS checks for far calls/jumps through call gates" + "not implemented.\\n"); + break; + case SegSSCheck: + panic("SS selector checks not implemented.\\n"); + break; + case SegIretCheck: + { + SegAttr csAttr = CSAttr; + if (!selector.si && !selector.ti) + return new GeneralProtection(psrc1 & 0xFFFF); + if (selector.rpl < csAttr.dpl) + return new GeneralProtection(psrc1 & 0xFFFF); + break; + } + case SegIntCSCheck: + panic("CS selector checks for interrupts and exceptions" + "not implemented.\\n"); + break; + default: + panic("Undefined segment check type.\\n"); + } + // Compute the address of the descriptor and set DestReg to it. if (selector.ti) { // A descriptor in the LDT diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index b48e8759f..f002b2cea 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -149,6 +149,7 @@ def operands {{ 'GDTRBase': ('ControlReg', 'uqw', 'MISCREG_TSG_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 205), 'GDTRLimit': ('ControlReg', 'uqw', 'MISCREG_TSG_LIMIT', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 206), 'CSBase': ('ControlReg', 'udw', 'MISCREG_CS_EFF_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 207), - 'TscOp': ('ControlReg', 'udw', 'MISCREG_TSC', (None, None, ['IsSerializeAfter', 'IsSerializing', 'IsNonSpeculative']), 208), + 'CSAttr': ('ControlReg', 'udw', 'MISCREG_CS_ATTR', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 208), + 'TscOp': ('ControlReg', 'udw', 'MISCREG_TSC', (None, None, ['IsSerializeAfter', 'IsSerializing', 'IsNonSpeculative']), 209), 'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 300) }}; -- cgit v1.2.3 From d4e7c7edd35d1f5e6771077eeca83369c1169a33 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:50:25 -0400 Subject: X86: Keep handy values like the operating mode in one register. --- src/arch/x86/isa/microops/regop.isa | 5 +++++ src/arch/x86/isa/operands.isa | 1 + src/arch/x86/miscregfile.cc | 30 +++++++++++++++++++++++++++++- src/arch/x86/miscregs.hh | 9 +++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 6bd26608e..35f319528 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -1100,6 +1100,11 @@ let {{ DestReg = TscOp; ''' + class Rdm5reg(RdRegOp): + code = ''' + DestReg = M5Reg; + ''' + class Wrdl(RegOp): code = ''' SegDescriptor desc = SrcReg1; diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index f002b2cea..446580c1b 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -151,5 +151,6 @@ def operands {{ 'CSBase': ('ControlReg', 'udw', 'MISCREG_CS_EFF_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 207), 'CSAttr': ('ControlReg', 'udw', 'MISCREG_CS_ATTR', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 208), 'TscOp': ('ControlReg', 'udw', 'MISCREG_TSC', (None, None, ['IsSerializeAfter', 'IsSerializing', 'IsNonSpeculative']), 209), + 'M5Reg': ('ControlReg', 'udw', 'MISCREG_M5_REG', (None, None, None), 210), 'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 300) }}; diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc index 930bf53c7..6abeb7d34 100644 --- a/src/arch/x86/miscregfile.cc +++ b/src/arch/x86/miscregfile.cc @@ -300,17 +300,39 @@ void MiscRegFile::setReg(int miscReg, CR0 toggled = regVal[miscReg] ^ val; CR0 newCR0 = val; Efer efer = regVal[MISCREG_EFER]; + HandyM5Reg m5reg = regVal[MISCREG_M5_REG]; if (toggled.pg && efer.lme) { if (newCR0.pg) { //Turning on long mode efer.lma = 1; + m5reg.mode = LongMode; regVal[MISCREG_EFER] = efer; } else { //Turning off long mode efer.lma = 0; + m5reg.mode = LegacyMode; regVal[MISCREG_EFER] = efer; } } + // Figure out what submode we're in. + if (m5reg.mode == LongMode) { + SegAttr csAttr = regVal[MISCREG_CS_ATTR]; + if (csAttr.longMode) + m5reg.submode = SixtyFourBitMode; + else + m5reg.submode = CompatabilityMode; + } else { + if (newCR0.pe) { + RFLAGS rflags = regVal[MISCREG_RFLAGS]; + if (rflags.vm) + m5reg.submode = Virtual8086Mode; + else + m5reg.submode = ProtectedMode; + } else { + m5reg.submode = RealMode; + } + } + regVal[MISCREG_M5_REG] = m5reg; if (toggled.pg) { tc->getITBPtr()->invalidateAll(); tc->getDTBPtr()->invalidateAll(); @@ -341,20 +363,26 @@ void MiscRegFile::setReg(int miscReg, { SegAttr toggled = regVal[miscReg] ^ val; SegAttr newCSAttr = val; + HandyM5Reg m5reg = regVal[MISCREG_M5_REG]; if (toggled.longMode) { - SegAttr newCSAttr = val; if (newCSAttr.longMode) { + if (m5reg.mode == LongMode) + m5reg.submode = SixtyFourBitMode; regVal[MISCREG_ES_EFF_BASE] = 0; regVal[MISCREG_CS_EFF_BASE] = 0; regVal[MISCREG_SS_EFF_BASE] = 0; regVal[MISCREG_DS_EFF_BASE] = 0; } else { + if (m5reg.mode == LongMode) + m5reg.submode = CompatabilityMode; regVal[MISCREG_ES_EFF_BASE] = regVal[MISCREG_ES_BASE]; regVal[MISCREG_CS_EFF_BASE] = regVal[MISCREG_CS_BASE]; regVal[MISCREG_SS_EFF_BASE] = regVal[MISCREG_SS_BASE]; regVal[MISCREG_DS_EFF_BASE] = regVal[MISCREG_DS_BASE]; } } + m5reg.cpl = newCSAttr.dpl; + regVal[MISCREG_M5_REG] = m5reg; } break; // These segments always actually use their bases, or in other words diff --git a/src/arch/x86/miscregs.hh b/src/arch/x86/miscregs.hh index 90f1d9fda..caa1e817b 100644 --- a/src/arch/x86/miscregs.hh +++ b/src/arch/x86/miscregs.hh @@ -130,6 +130,9 @@ namespace X86ISA // Flags register MISCREG_RFLAGS = MISCREG_DR_BASE + NumDRegs, + //Register to keep handy values like the CPU mode in. + MISCREG_M5_REG, + /* * Model Specific Registers */ @@ -563,6 +566,12 @@ namespace X86ISA Bitfield<0> cf; // Carry Flag EndBitUnion(RFLAGS) + BitUnion64(HandyM5Reg) + Bitfield<0> mode; + Bitfield<3, 1> submode; + Bitfield<5, 4> cpl; + EndBitUnion(HandyM5Reg) + /** * Control registers */ -- cgit v1.2.3 From a8384311d544391b03ff55f9384fdf8da2fa8bf6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:51:14 -0400 Subject: X86: Take advantage of the new meta register. --- src/arch/x86/predecoder.cc | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/predecoder.cc b/src/arch/x86/predecoder.cc index 407a09ec0..1d415ffea 100644 --- a/src/arch/x86/predecoder.cc +++ b/src/arch/x86/predecoder.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 The Hewlett-Packard Development Company + * Copyright (c) 2007-2008 The Hewlett-Packard Development Company * All rights reserved. * * Redistribution and use of this software in source and binary forms, @@ -55,9 +55,11 @@ * Authors: Gabe Black */ +#include "arch/x86/miscregs.hh" #include "arch/x86/predecoder.hh" #include "base/misc.hh" #include "base/trace.hh" +#include "cpu/thread_context.hh" #include "sim/host.hh" namespace X86ISA @@ -78,7 +80,9 @@ namespace X86ISA emi.modRM = 0; emi.sib = 0; - emi.mode = 0; + HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG); + emi.mode.mode = m5reg.mode; + emi.mode.submode = m5reg.submode; } void Predecoder::process() @@ -209,10 +213,12 @@ namespace X86ISA DPRINTF(Predecoder, "Found opcode %#x.\n", nextByte); emi.opcode.op = nextByte; + SegAttr csAttr = tc->readMiscRegNoEffect(MISCREG_CS_ATTR); + //Figure out the effective operand size. This can be overriden to //a fixed value at the decoder level. int logOpSize; - if(/*FIXME long mode*/1) + if (emi.mode.submode == SixtyFourBitMode) { if(emi.rex.w) logOpSize = 3; // 64 bit operand size @@ -221,7 +227,7 @@ namespace X86ISA else logOpSize = 2; // 32 bit operand size } - else if(/*FIXME default 32*/1) + else if(csAttr.defaultSize) { if(emi.legacy.op) logOpSize = 1; // 16 bit operand size @@ -242,14 +248,14 @@ namespace X86ISA //Figure out the effective address size. This can be overriden to //a fixed value at the decoder level. int logAddrSize; - if(/*FIXME 64-bit mode*/1) + if(emi.mode.submode == SixtyFourBitMode) { if(emi.legacy.addr) logAddrSize = 2; // 32 bit address size else logAddrSize = 3; // 64 bit address size } - else if(/*FIXME default 32*/1) + else if(csAttr.defaultSize) { if(emi.legacy.addr) logAddrSize = 1; // 16 bit address size @@ -264,6 +270,16 @@ namespace X86ISA logAddrSize = 1; // 16 bit address size } + SegAttr ssAttr = tc->readMiscRegNoEffect(MISCREG_SS_ATTR); + //Figure out the effective stack width. This can be overriden to + //a fixed value at the decoder level. + if(emi.mode.submode == SixtyFourBitMode) + emi.stackSize = 8; // 64 bit stack width + else if(ssAttr.defaultSize) + emi.stackSize = 4; // 32 bit stack width + else + emi.stackSize = 2; // 16 bit stack width + //Set the actual address size emi.addrSize = 1 << logAddrSize; @@ -299,7 +315,9 @@ namespace X86ISA ModRM modRM; modRM = nextByte; DPRINTF(Predecoder, "Found modrm byte %#x.\n", nextByte); - if (0) {//FIXME in 16 bit mode + SegAttr csAttr = tc->readMiscRegNoEffect(MISCREG_CS_ATTR); + if (emi.mode.submode != SixtyFourBitMode && + !csAttr.defaultSize) { //figure out 16 bit displacement size if(modRM.mod == 0 && modRM.rm == 6 || modRM.mod == 2) displacementSize = 2; -- cgit v1.2.3 From b05299253fdd5a8a913f2799b7cdd2df040c8559 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:51:50 -0400 Subject: X86: In non 64bit mode, throw a fault when a NULL segment is accessed. --- src/arch/x86/tlb.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index f5e214a88..5d101a5ae 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -571,6 +571,9 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) // If we're not in 64-bit mode, do protection/limit checks if (!efer.lma || !csAttr.longMode) { DPRINTF(TLB, "Not in long mode. Checking segment protection.\n"); + // Check for a NULL segment selector. + if (!tc->readMiscRegNoEffect(MISCREG_SEG_SEL(seg))) + return new GeneralProtection(0); SegAttr attr = tc->readMiscRegNoEffect(MISCREG_SEG_ATTR(seg)); if (!attr.writable && write) return new GeneralProtection(0); -- cgit v1.2.3 From 129831c116a6c7031093df624761f8d67bf4e115 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:51:57 -0400 Subject: X86: Make pushes and pops use the stack size instead of the data size. --- .../data_transfer/stack_operations.py | 96 +++++++++++----------- .../insts/general_purpose/flags/push_and_pop.py | 6 +- 2 files changed, 51 insertions(+), 51 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py index 6c51f3171..64efd7dc9 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py @@ -1,4 +1,4 @@ -# Copyright (c) 2007 The Hewlett-Packard Development Company +# Copyright (c) 2007-2008 The Hewlett-Packard Development Company # All rights reserved. # # Redistribution and use of this software in source and binary forms, @@ -58,8 +58,8 @@ def macroop POP_R { # Make the default data size of pops 64 bits in 64 bit mode .adjust_env oszIn64Override - ld t1, ss, [1, t0, rsp] - addi rsp, rsp, dsz + ld t1, ss, [1, t0, rsp], dataSize=ssz + addi rsp, rsp, ssz, dataSize=asz mov reg, reg, t1 }; @@ -67,10 +67,10 @@ def macroop POP_M { # Make the default data size of pops 64 bits in 64 bit mode .adjust_env oszIn64Override - ld t1, ss, [1, t0, rsp] - cda seg, sib, disp - addi rsp, rsp, dsz - st t1, seg, sib, disp + ld t1, ss, [1, t0, rsp], dataSize=ssz + cda seg, sib, disp, dataSize=ssz + addi rsp, rsp, ssz, dataSize=asz + st t1, seg, sib, disp, dataSize=ssz }; def macroop POP_P { @@ -78,17 +78,17 @@ def macroop POP_P { .adjust_env oszIn64Override rdip t7 - ld t1, ss, [1, t0, rsp] - cda seg, sib, disp - addi rsp, rsp, dsz - st t1, seg, riprel, disp + ld t1, ss, [1, t0, rsp], dataSize=ssz + cda seg, sib, disp, dataSize=ssz + addi rsp, rsp, ssz, dataSize=asz + st t1, seg, riprel, disp, dataSize=ssz }; def macroop PUSH_R { # Make the default data size of pops 64 bits in 64 bit mode .adjust_env oszIn64Override - stupd reg, ss, [1, t0, rsp], "-env.dataSize" + stupd reg, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz }; def macroop PUSH_I { @@ -96,15 +96,15 @@ def macroop PUSH_I { .adjust_env oszIn64Override limm t1, imm - stupd t1, ss, [1, t0, rsp], "-env.dataSize" + stupd t1, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz }; def macroop PUSH_M { # Make the default data size of pops 64 bits in 64 bit mode .adjust_env oszIn64Override - ld t1, seg, sib, disp - stupd t1, ss, [1, t0, rsp], "-env.dataSize" + ld t1, seg, sib, disp, dataSize=ssz + stupd t1, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz }; def macroop PUSH_P { @@ -112,48 +112,48 @@ def macroop PUSH_P { .adjust_env oszIn64Override rdip t7 - ld t1, seg, riprel, disp - stupd t1, ss, [1, t0, rsp], "-env.dataSize" + ld t1, seg, riprel, disp, dataSize=ssz + stupd t1, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz }; def macroop PUSHA { # Check all the stack addresses. We'll assume that if the beginning and # end are ok, then the stuff in the middle should be as well. - cda ss, [1, t0, rsp], "-env.dataSize" - cda ss, [1, t0, rsp], "-8 * env.dataSize" - stupd rax, ss, [1, t0, rsp], "-env.dataSize" - stupd rcx, ss, [1, t0, rsp], "-env.dataSize" - stupd rdx, ss, [1, t0, rsp], "-env.dataSize" - stupd rbx, ss, [1, t0, rsp], "-env.dataSize" - stupd rsp, ss, [1, t0, rsp], "-env.dataSize" - stupd rbp, ss, [1, t0, rsp], "-env.dataSize" - stupd rsi, ss, [1, t0, rsp], "-env.dataSize" - stupd rdi, ss, [1, t0, rsp], "-env.dataSize" + cda ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz + cda ss, [1, t0, rsp], "-8 * env.stackSize", dataSize=ssz + stupd rax, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz + stupd rcx, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz + stupd rdx, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz + stupd rbx, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz + stupd rsp, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz + stupd rbp, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz + stupd rsi, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz + stupd rdi, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz }; def macroop POPA { # Check all the stack addresses. We'll assume that if the beginning and # end are ok, then the stuff in the middle should be as well. - ld t1, ss, [1, t0, rsp], "0 * env.dataSize" - ld t2, ss, [1, t0, rsp], "7 * env.dataSize" - mov rdi, rdi, t1 - ld rsi, ss, [1, t0, rsp], "1 * env.dataSize" - ld rbp, ss, [1, t0, rsp], "2 * env.dataSize" - ld rbx, ss, [1, t0, rsp], "4 * env.dataSize" - ld rdx, ss, [1, t0, rsp], "5 * env.dataSize" - ld rcx, ss, [1, t0, rsp], "6 * env.dataSize" - mov rax, rax, t2 - addi rsp, rsp, "8 * env.dataSize" + ld t1, ss, [1, t0, rsp], "0 * env.stackSize", dataSize=ssz + ld t2, ss, [1, t0, rsp], "7 * env.stackSize", dataSize=ssz + mov rdi, rdi, t1, dataSize=ssz + ld rsi, ss, [1, t0, rsp], "1 * env.stackSize", dataSize=ssz + ld rbp, ss, [1, t0, rsp], "2 * env.stackSize", dataSize=ssz + ld rbx, ss, [1, t0, rsp], "4 * env.stackSize", dataSize=ssz + ld rdx, ss, [1, t0, rsp], "5 * env.stackSize", dataSize=ssz + ld rcx, ss, [1, t0, rsp], "6 * env.stackSize", dataSize=ssz + mov rax, rax, t2, dataSize=ssz + addi rsp, rsp, "8 * env.stackSize", dataSize=asz }; def macroop LEAVE { # Make the default data size of pops 64 bits in 64 bit mode .adjust_env oszIn64Override - mov t1, t1, rbp - ld rbp, ss, [1, t0, t1] - mov rsp, rsp, t1 - addi rsp, rsp, dsz + mov t1, t1, rbp, dataSize=asz + ld rbp, ss, [1, t0, t1], dataSize=ssz + mov rsp, rsp, t1, dataSize=asz + addi rsp, rsp, ssz, dataSize=asz }; def macroop ENTER_I_I { @@ -168,10 +168,10 @@ def macroop ENTER_I_I { # t1 is now the masked nesting level, and t2 is the amount of storage. # Push rbp. - stupd rbp, ss, [1, t0, rsp], "-env.dataSize" + stupd rbp, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz # Save the stack pointer for later - mov t6, t6, rsp + mov t6, t6, rsp, dataSize=asz # If the nesting level is zero, skip all this stuff. subi t0, t1, t0, flags=(EZF,), dataSize=2 @@ -183,8 +183,8 @@ def macroop ENTER_I_I { limm t4, "ULL(-1)", dataSize=8 topOfLoop: - ld t5, ss, [dsz, t4, rbp] - stupd t5, ss, [1, t0, rsp], "-env.dataSize" + ld t5, ss, [ssz, t4, rbp], dataSize=ssz + stupd t5, ss, [1, t0, rsp], "-env.stackSize" # If we're not done yet, loop subi t4, t4, 1, dataSize=8 @@ -193,10 +193,10 @@ topOfLoop: bottomOfLoop: # Push the old rbp onto the stack - stupd t6, ss, [1, t0, rsp], "-env.dataSize" + stupd t6, ss, [1, t0, rsp], "-env.stackSize" skipLoop: - sub rsp, rsp, t2 - mov rbp, rbp, t6 + sub rsp, rsp, t2, dataSize=asz + mov rbp, rbp, t6, dataSize=asz }; ''' diff --git a/src/arch/x86/isa/insts/general_purpose/flags/push_and_pop.py b/src/arch/x86/isa/insts/general_purpose/flags/push_and_pop.py index 5937ac074..59f6aaec2 100644 --- a/src/arch/x86/isa/insts/general_purpose/flags/push_and_pop.py +++ b/src/arch/x86/isa/insts/general_purpose/flags/push_and_pop.py @@ -58,14 +58,14 @@ def macroop PUSHF { .adjust_env oszIn64Override rflags t1 - stupd t1, ss, [1, t0, rsp], "-env.dataSize" + stupd t1, ss, [1, t0, rsp], "-env.stackSize", dataSize=ssz }; def macroop POPF { .adjust_env oszIn64Override - ld t1, ss, [1, t0, rsp] - addi rsp, rsp, dsz + ld t1, ss, [1, t0, rsp], dataSize=ssz + addi rsp, rsp, ssz wrflags t1, t0 }; ''' -- cgit v1.2.3 From 66f54a6037873420dbc3bc2c91723225538feddb Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:52:12 -0400 Subject: X86: Change how segment loading is performed. --- .../general_purpose/control_transfer/xreturn.py | 21 +++-- .../insts/general_purpose/data_transfer/move.py | 105 ++++++++++++++------- src/arch/x86/isa/microops/regop.isa | 98 ++++++++++--------- src/arch/x86/tlb.cc | 16 ++-- 4 files changed, 151 insertions(+), 89 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py index 0b2e81cbd..b18d48264 100644 --- a/src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py +++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py @@ -1,4 +1,4 @@ -# Copyright (c) 2007 The Hewlett-Packard Development Company +# Copyright (c) 2007-2008 The Hewlett-Packard Development Company # All rights reserved. # # Redistribution and use of this software in source and binary forms, @@ -85,7 +85,7 @@ def macroop RET_FAR { ld t1, ss, [1, t0, rsp] # Get the return CS - ld t2, ss, [1, t0, rsp], dsz + ld t2, ss, [1, t0, rsp], ssz # Get the rpl andi t3, t2, 0x3 @@ -96,12 +96,21 @@ def macroop RET_FAR { # that doesn't happen yet. # Do stuff if they're equal - chks t4, t2, flags=(EZF,) - fault "new GeneralProtection(0)", flags=(CEZF,) - ld t3, flatseg, [1, t0, t4], addressSize=8, dataSize=8 - wrdl cs, t3, t2 + andi t0, t2, 0xFC, flags=(EZF,), dataSize=2 + bri t0, label("processDescriptor"), flags=(CEZF,) + andi t3, t2, 0xF8, dataSize=8 + andi t0, t2, 0x4, flags=(EZF,), dataSize=2 + bri t0, label("globalDescriptor"), flags=(CEZF,) + ld t3, tsl, [1, t0, t3], dataSize=8 + bri t0, label("processDescriptor") +globalDescriptor: + ld t3, tsg, [1, t0, t3], dataSize=8 +processDescriptor: + chks t2, t3, IretCheck, dataSize=8 # There should be validity checks on the RIP checks here, but I'll do # that later. + wrdl reg, t3, t2 + wrsel reg, t2 wrip t0, t1 bri t0, label("end") diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py index 16196bcc8..d9a83dfde 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py @@ -237,65 +237,104 @@ def macroop MOV_REAL_S_P { }; def macroop MOV_S_R { - chks t1, regm, flags=(EZF,), dataSize=8 - bri t0, label("end"), flags=(CEZF,) - ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8 - wrdl reg, t2, regm -end: + andi t0, regm, 0xFC, flags=(EZF,), dataSize=2 + bri t0, label("processDescriptor"), flags=(CEZF,) + andi t2, regm, 0xF8, dataSize=8 + andi t0, regm, 0x4, flags=(EZF,), dataSize=2 + bri t0, label("globalDescriptor"), flags=(CEZF,) + ld t3, tsl, [1, t0, t2], dataSize=8 + bri t0, label("processDescriptor") +globalDescriptor: + ld t3, tsg, [1, t0, t2], dataSize=8 +processDescriptor: + chks regm, t3, dataSize=8 + wrdl reg, t3, regm wrsel reg, regm }; def macroop MOV_S_M { ld t1, seg, sib, disp, dataSize=2 - chks t2, t1, flags=(EZF,), dataSize=8 - bri t0, label("end"), flags=(CEZF,) - ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8 - wrdl reg, t2, t1 -end: + andi t0, t1, 0xFC, flags=(EZF,), dataSize=2 + bri t0, label("processDescriptor"), flags=(CEZF,) + andi t2, t1, 0xF8, dataSize=8 + andi t0, t1, 0x4, flags=(EZF,), dataSize=2 + bri t0, label("globalDescriptor"), flags=(CEZF,) + ld t3, tsl, [1, t0, t2], dataSize=8 + bri t0, label("processDescriptor") +globalDescriptor: + ld t3, tsg, [1, t0, t2], dataSize=8 +processDescriptor: + chks t1, t3, dataSize=8 + wrdl reg, t3, t1 wrsel reg, t1 }; def macroop MOV_S_P { rdip t7 ld t1, seg, riprel, disp, dataSize=2 - chks t2, t1, flags=(EZF,), dataSize=8 - bri t0, label("end"), flags=(CEZF,) - ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8 - wrdl reg, t2, t1 -end: + andi t0, t1, 0xFC, flags=(EZF,), dataSize=2 + bri t0, label("processDescriptor"), flags=(CEZF,) + andi t2, t1, 0xF8, dataSize=8 + andi t0, t1, 0x4, flags=(EZF,), dataSize=2 + bri t0, label("globalDescriptor"), flags=(CEZF,) + ld t3, tsl, [1, t0, t2], dataSize=8 + bri t0, label("processDescriptor") +globalDescriptor: + ld t3, tsg, [1, t0, t2], dataSize=8 +processDescriptor: + chks t1, t3, dataSize=8 + wrdl reg, t3, t1 wrsel reg, t1 }; def macroop MOVSS_S_R { - chks t1, regm, flags=(EZF,), dataSize=8 - # This actually needs to use the selector as the error code, but it would - # be hard to get that information into the instruction at the moment. - fault "new GeneralProtection(0)", flags=(CEZF,) - ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8 - wrdl reg, t2, regm + andi t0, regm, 0xFC, flags=(EZF,), dataSize=2 + bri t0, label("processDescriptor"), flags=(CEZF,) + andi t2, regm, 0xF8, dataSize=8 + andi t0, regm, 0x4, flags=(EZF,), dataSize=2 + bri t0, label("globalDescriptor"), flags=(CEZF,) + ld t3, tsl, [1, t0, t2], dataSize=8 + bri t0, label("processDescriptor") +globalDescriptor: + ld t3, tsg, [1, t0, t2], dataSize=8 +processDescriptor: + chks regm, t3, SSCheck, dataSize=8 + wrdl reg, t3, regm wrsel reg, regm }; def macroop MOVSS_S_M { ld t1, seg, sib, disp, dataSize=2 - chks t2, t1, flags=(EZF,), dataSize=8 - # This actually needs to use the selector as the error code, but it would - # be hard to get that information into the instruction at the moment. - fault "new GeneralProtection(0)", flags=(CEZF,) - ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8 - wrdl reg, t2, t1 + andi t0, t1, 0xFC, flags=(EZF,), dataSize=2 + bri t0, label("processDescriptor"), flags=(CEZF,) + andi t2, t1, 0xF8, dataSize=8 + andi t0, t1, 0x4, flags=(EZF,), dataSize=2 + bri t0, label("globalDescriptor"), flags=(CEZF,) + ld t3, tsl, [1, t0, t2], dataSize=8 + bri t0, label("processDescriptor") +globalDescriptor: + ld t3, tsg, [1, t0, t2], dataSize=8 +processDescriptor: + chks t1, t3, SSCheck, dataSize=8 + wrdl reg, t3, t1 wrsel reg, t1 }; def macroop MOVSS_S_P { rdip t7 ld t1, seg, riprel, disp, dataSize=2 - chks t2, t1, flags=(EZF,), dataSize=8 - # This actually needs to use the selector as the error code, but it would - # be hard to get that information into the instruction at the moment. - fault "new GeneralProtection(0)", flags=(CEZF,) - ld t2, flatseg, [1, t0, t1], addressSize=8, dataSize=8 - wrdl reg, t2, t1 + andi t0, t1, 0xFC, flags=(EZF,), dataSize=2 + bri t0, label("processDescriptor"), flags=(CEZF,) + andi t2, t1, 0xF8, dataSize=8 + andi t0, t1, 0x4, flags=(EZF,), dataSize=2 + bri t0, label("globalDescriptor"), flags=(CEZF,) + ld t3, tsl, [1, t0, t2], dataSize=8 + bri t0, label("processDescriptor") +globalDescriptor: + ld t3, tsg, [1, t0, t2], dataSize=8 +processDescriptor: + chks t1, t3, SSCheck, dataSize=8 + wrdl reg, t3, t1 wrsel reg, t1 }; ''' diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 35f319528..b751b9b4f 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -1030,7 +1030,9 @@ let {{ src1, src2, flags, dataSize) code = ''' // The selector is in source 1 and can be at most 16 bits. - SegSelector selector = psrc1; + SegSelector selector = DestReg; + SegDescriptor desc = SrcReg1; + HandyM5Reg m5reg = M5Reg; switch (imm8) { @@ -1044,15 +1046,31 @@ let {{ "not implemented.\\n"); break; case SegSSCheck: - panic("SS selector checks not implemented.\\n"); + if (selector.si || selector.ti) { + if (!desc.p) { + //FIXME This needs to also push the selector. + return new StackFault; + } + } else { + if ((m5reg.mode != SixtyFourBitMode || m5reg.cpl == 3) || + !(desc.s == 1 && + desc.type.codeOrData == 0 && desc.type.w) || + (desc.dpl != m5reg.cpl) || + (selector.rpl != m5reg.cpl)) { + return new GeneralProtection(psrc1 & 0xFFFF); + } + } break; case SegIretCheck: { - SegAttr csAttr = CSAttr; - if (!selector.si && !selector.ti) - return new GeneralProtection(psrc1 & 0xFFFF); - if (selector.rpl < csAttr.dpl) + if ((!selector.si && !selector.ti) || + (selector.rpl < m5reg.cpl) || + !(desc.s == 1 && desc.type.codeOrData == 1) || + (!desc.type.c && desc.dpl != selector.rpl) || + (desc.type.c && desc.dpl > selector.rpl)) return new GeneralProtection(psrc1 & 0xFFFF); + if (!desc.p) + return new SegmentNotPresent; break; } case SegIntCSCheck: @@ -1062,21 +1080,6 @@ let {{ default: panic("Undefined segment check type.\\n"); } - - // Compute the address of the descriptor and set DestReg to it. - if (selector.ti) { - // A descriptor in the LDT - Addr target = (selector.si << 3) + LDTRBase; - if (!LDTRSel || (selector.si << 3) + dataSize > LDTRLimit) - fault = new GeneralProtection(selector & mask(16)); - DestReg = target; - } else { - // A descriptor in the GDT - Addr target = (selector.si << 3) + GDTRBase; - if ((selector.si << 3) + dataSize > GDTRLimit) - fault = new GeneralProtection(selector & mask(16)); - DestReg = target; - } ''' flag_code = ''' // Check for a NULL selector and set ZF,EZF appropriately. @@ -1108,32 +1111,39 @@ let {{ class Wrdl(RegOp): code = ''' SegDescriptor desc = SrcReg1; - SegAttr attr = 0; - attr.dpl = desc.dpl; - attr.defaultSize = desc.d; - if (!desc.s) { + SegSelector selector = SrcReg2; + if (selector.si || selector.ti) { + SegAttr attr = 0; + attr.dpl = desc.dpl; + attr.defaultSize = desc.d; + if (!desc.s) { + SegBaseDest = SegBaseDest; + SegLimitDest = SegLimitDest; + SegAttrDest = SegAttrDest; + panic("System segment encountered.\\n"); + } else { + if (!desc.p) + panic("Segment not present.\\n"); + if (desc.type.codeOrData) { + attr.readable = desc.type.r; + attr.longMode = desc.l; + } else { + attr.expandDown = desc.type.e; + attr.readable = 1; + attr.writable = desc.type.w; + } + Addr base = desc.baseLow | (desc.baseHigh << 24); + Addr limit = desc.limitLow | (desc.limitHigh << 16); + if (desc.g) + limit = (limit << 12) | mask(12); + SegBaseDest = base; + SegLimitDest = limit; + SegAttrDest = attr; + } + } else { SegBaseDest = SegBaseDest; SegLimitDest = SegLimitDest; SegAttrDest = SegAttrDest; - panic("System segment encountered.\\n"); - } else { - if (!desc.p) - panic("Segment not present.\\n"); - if (desc.type.codeOrData) { - attr.readable = desc.type.r; - attr.longMode = desc.l; - } else { - attr.expandDown = desc.type.e; - attr.readable = 1; - attr.writable = desc.type.w; - } - Addr base = desc.baseLow | (desc.baseHigh << 24); - Addr limit = desc.limitLow | (desc.limitHigh << 16); - if (desc.g) - limit = (limit << 12) | mask(12); - SegBaseDest = base; - SegLimitDest = limit; - SegAttrDest = attr; } ''' }}; diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 5d101a5ae..ba8f63a0e 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -574,14 +574,18 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) // Check for a NULL segment selector. if (!tc->readMiscRegNoEffect(MISCREG_SEG_SEL(seg))) return new GeneralProtection(0); - SegAttr attr = tc->readMiscRegNoEffect(MISCREG_SEG_ATTR(seg)); - if (!attr.writable && write) - return new GeneralProtection(0); - if (!attr.readable && !write && !execute) - return new GeneralProtection(0); + bool expandDown = false; + if (seg >= SEGMENT_REG_ES && seg <= SEGMENT_REG_HS) { + SegAttr attr = tc->readMiscRegNoEffect(MISCREG_SEG_ATTR(seg)); + if (!attr.writable && write) + return new GeneralProtection(0); + if (!attr.readable && !write && !execute) + return new GeneralProtection(0); + expandDown = attr.expandDown; + } Addr base = tc->readMiscRegNoEffect(MISCREG_SEG_BASE(seg)); Addr limit = tc->readMiscRegNoEffect(MISCREG_SEG_LIMIT(seg)); - if (!attr.expandDown) { + if (expandDown) { DPRINTF(TLB, "Checking an expand down segment.\n"); // We don't have to worry about the access going around the // end of memory because accesses will be broken up into -- cgit v1.2.3 From 8d2416c6e9ec56dc2addd594eb7f7cab0d58b951 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:53:01 -0400 Subject: X86: Implement a partial, sort of correct version of the protected mode variant of iret. --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 8 +- .../control_transfer/interrupts_and_exceptions.py | 193 ++++++++++++++++++++- 2 files changed, 191 insertions(+), 10 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index 332ae1641..8729f417d 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -1,4 +1,4 @@ -// Copyright (c) 2007 The Hewlett-Packard Development Company +// Copyright (c) 2007-2008 The Hewlett-Packard Development Company // All rights reserved. // // Redistribution and use of this software in source and binary forms, @@ -423,7 +423,11 @@ 0x0: Inst::UD2(); default: into(); } - 0x7: iret(); + 0x7: decode MODE_SUBMODE { + 0x4: Inst::IRET_REAL(); + 0x3: Inst::IRET_VIRT(); + default: Inst::IRET_PROT(); + } } } 0x1A: decode OPCODE_OP_BOTTOM3 { diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py index 7039b4b5c..327361746 100644 --- a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py +++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py @@ -1,4 +1,4 @@ -# Copyright (c) 2007 The Hewlett-Packard Development Company +# Copyright (c) 2007-2008 The Hewlett-Packard Development Company # All rights reserved. # # Redistribution and use of this software in source and binary forms, @@ -53,16 +53,193 @@ # # Authors: Gabe Black -microcode = "" +microcode = ''' +def macroop IRET_REAL { + panic "Real mode iret isn't implemented!" +}; + +def macroop IRET_PROT { + .adjust_env oszIn64Override + + # Check for a nested task. This isn't supported at the moment. + rflag t1, NT + panic "Task switching with iret is unimplemented!", flags=(nCEZF,) + + #t1 = temp_RIP + #t2 = temp_CS + #t3 = temp_RFLAGS + #t4 = handy m5 register + + # Pop temp_RIP, temp_CS, and temp_RFLAGS + ld t1, ss, [1, t0, rsp], "0 * env.stackSize", dataSize=ssz + ld t2, ss, [1, t0, rsp], "1 * env.stackSize", dataSize=ssz + ld t3, ss, [1, t0, rsp], "2 * env.stackSize", dataSize=ssz + + + +### +### Handle if we're returning to virtual 8086 mode. +### + + #IF ((temp_RFLAGS.VM=1) && (CPL=0) && (LEGACY_MODE)) + # IRET_FROM_PROTECTED_TO_VIRTUAL + + #temp_RFLAGS.VM != 1 + rcri t0, t3, 18, flags=(ECF,) + bri t0, label("protToVirtFallThrough"), flags=(nCECF,) + + #CPL=0 + rdm5reg t4 + andi t0, t4, 0x30, flags=(EZF,) + bri t0, label("protToVirtFallThrough"), flags=(nCEZF,) + + #(LEGACY_MODE) + rcri t0, t4, 1, flags=(ECF,) + bri t0, label("protToVirtFallThrough"), flags=(nCECF,) + + panic "iret to virtual mode not supported" + +protToVirtFallThrough: + + + + #temp_CPL = temp_CS.rpl + andi t5, t2, 0x3 + + +### +### Read in the info for the new CS segment. +### + + #CS = READ_DESCRIPTOR (temp_CS, iret_chk) + andi t0, t2, 0xFC, flags=(EZF,), dataSize=2 + bri t0, label("processCSDescriptor"), flags=(CEZF,) + andi t6, t2, 0xF8, dataSize=8 + andi t0, t2, 0x4, flags=(EZF,), dataSize=2 + bri t0, label("globalCSDescriptor"), flags=(CEZF,) + ld t6, tsl, [1, t0, t6], dataSize=8 + bri t0, label("processCSDescriptor") +globalCSDescriptor: + ld t6, tsg, [1, t0, t6], dataSize=8 +processCSDescriptor: + chks t2, t6, dataSize=8 + + # This actually updates state which is wrong. It should wait until we know + # we're not going to fault. Unfortunately, that's hard to do. + wrdl cs, t6, t2 + wrsel cs, t2 + + #CPL = temp_CPL + + +### +### Get the new stack pointer and stack segment off the old stack if necessary, +### and piggyback on the logic to check the new RIP value. +### + #IF ((64BIT_MODE) || (temp_CPL!=CPL)) + #{ + + #(64BIT_MODE) + andi t0, t4, 0xE, flags=(EZF,) + # Since we just found out we're in 64 bit mode, take advantage and + # do the appropriate RIP checks. + bri t0, label("doPopStackStuffAndCheckRIP"), flags=(CEZF,) + + # Here, we know we're -not- in 64 bit mode, so we should do the + # appropriate/other RIP checks. + # if temp_RIP > CS.limit throw #GP(0) + rdlimit t6, cs + subi t0, t1, t6, flags=(ECF,) + fault "new GeneralProtection(0)", flags=(CECF,) + + #(temp_CPL!=CPL) + srli t7, t4, 4 + xor t7, t7, t5 + andi t0, t7, 0x3, flags=(EZF,) + bri t0, label("doPopStackStuff"), flags=(nCEZF,) + # We can modify user visible state here because we're know + # we're done with things that can fault. + addi rsp, rsp, "3 * env.stackSize" + bri t0, label("fallThroughPopStackStuff") + +doPopStackStuffAndCheckRIP: + # Check if the RIP is canonical. + sra t7, t1, 47, flags=(EZF,), dataSize=ssz + # if t7 isn't 0 or -1, it wasn't canonical. + bri t0, label("doPopStackStuff"), flags=(CEZF,) + addi t0, t7, 1, flags=(EZF,), dataSize=ssz + fault "new GeneralProtection(0)", flags=(nCEZF,) + +doPopStackStuff: + # POP.v temp_RSP + ld t6, ss, [1, t0, rsp], "3 * env.dataSize", dataSize=ssz + # POP.v temp_SS + ld t2, ss, [1, t0, rsp], "4 * env.dataSize", dataSize=ssz + # SS = READ_DESCRIPTOR (temp_SS, ss_chk) + andi t0, t2, 0xFC, flags=(EZF,), dataSize=2 + bri t0, label("processSSDescriptor"), flags=(CEZF,) + andi t7, t2, 0xF8, dataSize=8 + andi t0, t2, 0x4, flags=(EZF,), dataSize=2 + bri t0, label("globalSSDescriptor"), flags=(CEZF,) + ld t7, tsl, [1, t0, t7], dataSize=8 + bri t0, label("processSSDescriptor") +globalSSDescriptor: + ld t7, tsg, [1, t0, t7], dataSize=8 +processSSDescriptor: + chks t2, t7, dataSize=8 + + # This actually updates state which is wrong. It should wait until we know + # we're not going to fault. Unfortunately, that's hard to do. + wrdl cs, t7, t2 + wrsel cs, t2 + +### +### From this point downwards, we can't fault. We can update user visible state. +### + # RSP.s = temp_RSP + mov rsp, rsp, t6, dataSize=ssz + + #} + +fallThroughPopStackStuff: + + #IF (changing CPL) + #{ + srli t7, t4, 4 + xor t7, t7, t5 + andi t0, t7, 0x3, flags=(EZF,) + bri t0, label("skipSegmentSquashing"), flags=(CEZF,) + + # The attribute register needs to keep track of more info before this will + # work the way it needs to. + # FOR (seg = ES, DS, FS, GS) + # IF ((seg.attr.dpl < cpl && ((seg.attr.type = 'data') + # || (seg.attr.type = 'non-conforming-code'))) + # { + # seg = NULL + # } + #} + +skipSegmentSquashing: + + # Ignore this for now. + #RFLAGS.v = temp_RFLAGS + # VIF,VIP,IOPL only changed if (old_CPL = 0) + # IF only changed if (old_CPL <= old_RFLAGS.IOPL) + # VM unchanged + # RF cleared + + #RIP = temp_RIP + wrip t0, t1, dataSize=ssz +}; + +def macroop IRET_VIRT { + panic "Virtual mode iret isn't implemented!" +}; +''' #let {{ # class INT(Inst): # "GenFault ${new UnimpInstFault}" # class INTO(Inst): # "GenFault ${new UnimpInstFault}" -# class IRET(Inst): -# "GenFault ${new UnimpInstFault}" -# class IRETD(Inst): -# "GenFault ${new UnimpInstFault}" -# class IRETQ(Inst): -# "GenFault ${new UnimpInstFault}" #}}; -- cgit v1.2.3 From 8a6723e0380bf501e305fb2dd72f0e9079f158b2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:53:37 -0400 Subject: X86: Make the apic version register work. --- src/arch/x86/miscregfile.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc index 6abeb7d34..7fce43c1d 100644 --- a/src/arch/x86/miscregfile.cc +++ b/src/arch/x86/miscregfile.cc @@ -222,8 +222,8 @@ void MiscRegFile::setReg(int miscReg, panic("Local APIC ID register unimplemented.\n"); break; case MISCREG_APIC_VERSION: - panic("Local APIC Version register is read only.\n"); - break; + // The Local APIC Version register is read only. + return; case MISCREG_APIC_TASK_PRIORITY: panic("Local APIC Task Priority register unimplemented.\n"); break; -- cgit v1.2.3 From ed23a4970bde6eea4a72aa0e33a87aad5713a427 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:53:43 -0400 Subject: X86: Make the apic ID register work. --- src/arch/x86/miscregfile.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc index 7fce43c1d..d52d56915 100644 --- a/src/arch/x86/miscregfile.cc +++ b/src/arch/x86/miscregfile.cc @@ -219,7 +219,7 @@ void MiscRegFile::setReg(int miscReg, } switch (miscReg) { case MISCREG_APIC_ID: - panic("Local APIC ID register unimplemented.\n"); + newVal = val & 0xFF; break; case MISCREG_APIC_VERSION: // The Local APIC Version register is read only. -- cgit v1.2.3 From e9c481ea4ae7d72d6a53bc80c7f867578179f00c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:53:50 -0400 Subject: X86: Make the logical destination and destination format work. --- src/arch/x86/miscregfile.cc | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc index d52d56915..46ee3a7db 100644 --- a/src/arch/x86/miscregfile.cc +++ b/src/arch/x86/miscregfile.cc @@ -106,6 +106,8 @@ void MiscRegFile::clear() { // Blank everything. 0 might not be an appropriate value for some things. memset(regVal, 0, NumMiscRegs * sizeof(MiscReg)); + //Set the local apic DFR to the flat model. + regVal[MISCREG_APIC_DESTINATION_FORMAT] = (MiscReg)(-1); } MiscReg MiscRegFile::readRegNoEffect(int miscReg) @@ -151,12 +153,6 @@ MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc) case MISCREG_APIC_EOI: panic("Local APIC EOI register unimplemented.\n"); break; - case MISCREG_APIC_LOGICAL_DESTINATION: - panic("Local APIC Logical Destination register unimplemented.\n"); - break; - case MISCREG_APIC_DESTINATION_FORMAT: - panic("Local APIC Destination Format register unimplemented.\n"); - break; case MISCREG_APIC_ERROR_STATUS: regVal[MISCREG_APIC_INTERNAL_STATE] &= ~ULL(0x1); break; @@ -237,10 +233,10 @@ void MiscRegFile::setReg(int miscReg, panic("Local APIC EOI register unimplemented.\n"); break; case MISCREG_APIC_LOGICAL_DESTINATION: - panic("Local APIC Logical Destination register unimplemented.\n"); + newVal = val & 0xFF000000; break; case MISCREG_APIC_DESTINATION_FORMAT: - panic("Local APIC Destination Format register unimplemented.\n"); + newVal = val | 0x0FFFFFFF; break; case MISCREG_APIC_SPURIOUS_INTERRUPT_VECTOR: regVal[MISCREG_APIC_INTERNAL_STATE] &= ~ULL(1 << 1); -- cgit v1.2.3 From 69000baef3ad409607ca8682d4d0afd29bc8f263 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:54:01 -0400 Subject: X86: Make the apic task priority register work. --- src/arch/x86/miscregfile.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc index 46ee3a7db..ee71842d2 100644 --- a/src/arch/x86/miscregfile.cc +++ b/src/arch/x86/miscregfile.cc @@ -141,9 +141,6 @@ MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc) "are unimplemented.\n"); } switch (miscReg) { - case MISCREG_APIC_TASK_PRIORITY: - panic("Local APIC Task Priority register unimplemented.\n"); - break; case MISCREG_APIC_ARBITRATION_PRIORITY: panic("Local APIC Arbitration Priority register unimplemented.\n"); break; @@ -221,7 +218,7 @@ void MiscRegFile::setReg(int miscReg, // The Local APIC Version register is read only. return; case MISCREG_APIC_TASK_PRIORITY: - panic("Local APIC Task Priority register unimplemented.\n"); + newVal = val & 0xFF; break; case MISCREG_APIC_ARBITRATION_PRIORITY: panic("Local APIC Arbitration Priority register unimplemented.\n"); -- cgit v1.2.3 From b10742ee2b01213999ba9a3706093f5946097341 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:54:05 -0400 Subject: X86: Make the apic isr and irr work. --- src/arch/x86/miscregfile.cc | 9 --------- 1 file changed, 9 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc index ee71842d2..1e02391e6 100644 --- a/src/arch/x86/miscregfile.cc +++ b/src/arch/x86/miscregfile.cc @@ -127,19 +127,10 @@ MiscReg MiscRegFile::readRegNoEffect(int miscReg) MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc) { if (miscReg >= MISCREG_APIC_START && miscReg <= MISCREG_APIC_END) { - if (miscReg >= MISCREG_APIC_IN_SERVICE(0) && - miscReg <= MISCREG_APIC_IN_SERVICE(15)) { - panic("Local APIC In-Service registers are unimplemented.\n"); - } if (miscReg >= MISCREG_APIC_TRIGGER_MODE(0) && miscReg <= MISCREG_APIC_TRIGGER_MODE(15)) { panic("Local APIC Trigger Mode registers are unimplemented.\n"); } - if (miscReg >= MISCREG_APIC_INTERRUPT_REQUEST(0) && - miscReg <= MISCREG_APIC_INTERRUPT_REQUEST(15)) { - panic("Local APIC Interrupt Request registers " - "are unimplemented.\n"); - } switch (miscReg) { case MISCREG_APIC_ARBITRATION_PRIORITY: panic("Local APIC Arbitration Priority register unimplemented.\n"); -- cgit v1.2.3 From 6b8d0363ee271a1b36dd03e3bac5e62efc52aad4 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:54:12 -0400 Subject: X86: Rename the divide count register to divide configuration. --- src/arch/x86/miscregfile.cc | 7 ++----- src/arch/x86/miscregs.hh | 4 ++-- src/arch/x86/tlb.cc | 2 +- 3 files changed, 5 insertions(+), 8 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc index 1e02391e6..64dac6147 100644 --- a/src/arch/x86/miscregfile.cc +++ b/src/arch/x86/miscregfile.cc @@ -158,9 +158,6 @@ MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc) case MISCREG_APIC_CURRENT_COUNT: panic("Local APIC Current Count register unimplemented.\n"); break; - case MISCREG_APIC_DIVIDE_COUNT: - panic("Local APIC Divide Count register unimplemented.\n"); - break; } } switch (miscReg) { @@ -270,8 +267,8 @@ void MiscRegFile::setReg(int miscReg, case MISCREG_APIC_CURRENT_COUNT: panic("Local APIC Current Count register unimplemented.\n"); break; - case MISCREG_APIC_DIVIDE_COUNT: - panic("Local APIC Divide Count register unimplemented.\n"); + case MISCREG_APIC_DIVIDE_CONFIGURATION: + newVal = val & 0xB; break; } setRegNoEffect(miscReg, newVal); diff --git a/src/arch/x86/miscregs.hh b/src/arch/x86/miscregs.hh index caa1e817b..5a6ee752d 100644 --- a/src/arch/x86/miscregs.hh +++ b/src/arch/x86/miscregs.hh @@ -397,8 +397,8 @@ namespace X86ISA MISCREG_APIC_LVT_ERROR, MISCREG_APIC_INITIAL_COUNT, MISCREG_APIC_CURRENT_COUNT, - MISCREG_APIC_DIVIDE_COUNT, - MISCREG_APIC_END = MISCREG_APIC_DIVIDE_COUNT, + MISCREG_APIC_DIVIDE_CONFIGURATION, + MISCREG_APIC_END = MISCREG_APIC_DIVIDE_CONFIGURATION, MISCREG_APIC_INTERNAL_STATE, diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index ba8f63a0e..692d6d022 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -780,7 +780,7 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) regNum = MISCREG_APIC_CURRENT_COUNT; break; case 0x3E0: - regNum = MISCREG_APIC_DIVIDE_COUNT; + regNum = MISCREG_APIC_DIVIDE_CONFIGURATION; break; default: // A reserved register field. -- cgit v1.2.3 From 81936ae2ed0368f4687e74374bf32575376bf9df Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:54:19 -0400 Subject: X86: Add an event for the apic timer timeout. It doesn't get used yet. --- src/arch/x86/miscregfile.cc | 28 +++++++++++++++++++++------- src/arch/x86/miscregfile.hh | 19 ++++++++++++++++++- 2 files changed, 39 insertions(+), 8 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc index 64dac6147..f40b1adf5 100644 --- a/src/arch/x86/miscregfile.cc +++ b/src/arch/x86/miscregfile.cc @@ -110,6 +110,16 @@ void MiscRegFile::clear() regVal[MISCREG_APIC_DESTINATION_FORMAT] = (MiscReg)(-1); } +int divideFromConf(MiscReg conf) +{ + // This figures out what division we want from the division configuration + // register in the local APIC. The encoding is a little odd but it can + // be deciphered fairly easily. + int shift = ((conf & 0x8) >> 1) | (conf & 0x3); + shift = (shift + 1) % 8; + return 1 << shift; +}; + MiscReg MiscRegFile::readRegNoEffect(int miscReg) { // Make sure we're not dealing with an illegal control register. @@ -152,11 +162,10 @@ MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc) panic("Local APIC Interrupt Command high" " register unimplemented.\n"); break; - case MISCREG_APIC_INITIAL_COUNT: - panic("Local APIC Initial Count register unimplemented.\n"); - break; case MISCREG_APIC_CURRENT_COUNT: - panic("Local APIC Current Count register unimplemented.\n"); + return (regVal[miscReg] - tc->getCpuPtr()->curCycle()) / + (16 * divideFromConf( + regVal[MISCREG_APIC_DIVIDE_CONFIGURATION])); break; } } @@ -262,11 +271,16 @@ void MiscRegFile::setReg(int miscReg, } break; case MISCREG_APIC_INITIAL_COUNT: - panic("Local APIC Initial Count register unimplemented.\n"); + newVal = bits(val, 31, 0); + regVal[MISCREG_APIC_CURRENT_COUNT] = + tc->getCpuPtr()->curCycle() + + (16 * divideFromConf( + regVal[MISCREG_APIC_DIVIDE_CONFIGURATION])) * newVal; + //FIXME This should schedule the timer event. break; case MISCREG_APIC_CURRENT_COUNT: - panic("Local APIC Current Count register unimplemented.\n"); - break; + //Local APIC Current Count register is read only. + return; case MISCREG_APIC_DIVIDE_CONFIGURATION: newVal = val & 0xB; break; diff --git a/src/arch/x86/miscregfile.hh b/src/arch/x86/miscregfile.hh index e095e06e9..3abe4ec58 100644 --- a/src/arch/x86/miscregfile.hh +++ b/src/arch/x86/miscregfile.hh @@ -29,7 +29,7 @@ */ /* - * Copyright (c) 2007 The Hewlett-Packard Development Company + * Copyright (c) 2007-2008 The Hewlett-Packard Development Company * All rights reserved. * * Redistribution and use of this software in source and binary forms, @@ -91,6 +91,8 @@ #include "arch/x86/faults.hh" #include "arch/x86/miscregs.hh" #include "arch/x86/types.hh" +#include "sim/eventq.hh" +#include "sim/host.hh" #include @@ -98,6 +100,7 @@ class Checkpoint; namespace X86ISA { + std::string getMiscRegName(RegIndex); //These will have to be updated in the future. @@ -109,6 +112,20 @@ namespace X86ISA protected: MiscReg regVal[NumMiscRegs]; + class ApicTimerEvent : public Event + { + public: + ApicTimerEvent() : Event(&mainEventQueue) + {} + + void process() + { + warn("Local APIC timer event doesn't do anything!\n"); + } + }; + + ApicTimerEvent apicTimerEvent; + public: void clear(); -- cgit v1.2.3 From 31d40ad7c22651eb88271abddacf416aa7c2adf2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:58:19 -0400 Subject: X86: Implement and hook up STI and CLI instructions. --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 4 ++-- .../insts/general_purpose/flags/set_and_clear.py | 22 +++++++++++++++------- 2 files changed, 17 insertions(+), 9 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index 8729f417d..005864f02 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -553,8 +553,8 @@ 0x1F: decode OPCODE_OP_BOTTOM3 { 0x0: CLC(); 0x1: STC(); - 0x2: WarnUnimpl::cli(); - 0x3: WarnUnimpl::sti(); + 0x2: CLI(); + 0x3: STI(); 0x4: CLD(); 0x5: STD(); //0x6: group4(); diff --git a/src/arch/x86/isa/insts/general_purpose/flags/set_and_clear.py b/src/arch/x86/isa/insts/general_purpose/flags/set_and_clear.py index 4c655e0b2..e151dc61d 100644 --- a/src/arch/x86/isa/insts/general_purpose/flags/set_and_clear.py +++ b/src/arch/x86/isa/insts/general_purpose/flags/set_and_clear.py @@ -1,4 +1,4 @@ -# Copyright (c) 2007 The Hewlett-Packard Development Company +# Copyright (c) 2007-2008 The Hewlett-Packard Development Company # All rights reserved. # # Redistribution and use of this software in source and binary forms, @@ -84,10 +84,18 @@ def macroop CMC { ruflags t1 wruflagsi t1, "CFBit" }; + +def macroop STI { + rflags t1 + limm t2, "IFBit" + or t1, t1, t2 + wrflags t1, t0 +}; + +def macroop CLI { + rflags t1 + limm t2, "~IFBit" + and t1, t1, t2 + wrflags t1, t0 +}; ''' -#let {{ -# class CLI(Inst): -# "GenFault ${new UnimpInstFault}" -# class STI(Inst): -# "GenFault ${new UnimpInstFault}" -#}}; -- cgit v1.2.3 From 4f4ff17578846018e06b0b9b047df96a8346efd9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:58:27 -0400 Subject: X86: Make the disassembly for halt conform with the other microops. --- src/arch/x86/isa/microops/specop.isa | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/specop.isa b/src/arch/x86/isa/microops/specop.isa index 6bcc7ff91..ad14b54a3 100644 --- a/src/arch/x86/isa/microops/specop.isa +++ b/src/arch/x86/isa/microops/specop.isa @@ -1,4 +1,4 @@ -// Copyright (c) 2007 The Hewlett-Packard Development Company +// Copyright (c) 2007-2008 The Hewlett-Packard Development Company // All rights reserved. // // Redistribution and use of this software in source and binary forms, @@ -95,6 +95,9 @@ output header {{ } %(BasicExecDeclare)s + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; }; }}; @@ -201,6 +204,16 @@ output decoder {{ return response.str(); } + + std::string MicroHalt::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream response; + + printMnemonic(response, instMnem, mnemonic); + + return response.str(); + } }}; let {{ -- cgit v1.2.3 From bceaa257a38d62c91317cecc78f4dba46654eb93 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 00:58:36 -0400 Subject: X86: Make the e820 table manually or automatically configurable from python. --- src/arch/x86/SConscript | 2 + src/arch/x86/X86System.py | 6 ++- src/arch/x86/bios/E820.py | 73 ++++++++++++++++++++++++++++++ src/arch/x86/bios/e820.cc | 103 +++++++++++++++++++++++++++++++++++++++++++ src/arch/x86/bios/e820.hh | 100 +++++++++++++++++++++++++++++++++++++++++ src/arch/x86/linux/system.cc | 61 ++----------------------- src/arch/x86/linux/system.hh | 4 +- 7 files changed, 289 insertions(+), 60 deletions(-) create mode 100644 src/arch/x86/bios/E820.py create mode 100644 src/arch/x86/bios/e820.cc create mode 100644 src/arch/x86/bios/e820.hh (limited to 'src/arch') diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript index 09967b0d3..184bb4809 100644 --- a/src/arch/x86/SConscript +++ b/src/arch/x86/SConscript @@ -110,8 +110,10 @@ if env['TARGET_ISA'] == 'x86': if env['FULL_SYSTEM']: SimObject('X86System.py') + SimObject('bios/E820.py') # Full-system sources + Source('bios/e820.cc') Source('linux/system.cc') Source('pagetable_walker.cc') Source('smbios.cc') diff --git a/src/arch/x86/X86System.py b/src/arch/x86/X86System.py index f73764540..b4ec393c3 100644 --- a/src/arch/x86/X86System.py +++ b/src/arch/x86/X86System.py @@ -1,4 +1,4 @@ -# Copyright (c) 2007 The Hewlett-Packard Development Company +# Copyright (c) 2007-2008 The Hewlett-Packard Development Company # All rights reserved. # # Redistribution and use of this software in source and binary forms, @@ -54,6 +54,7 @@ # Authors: Gabe Black from m5.params import * +from E820 import X86E820Table, X86E820Entry from System import System class X86System(System): @@ -61,3 +62,6 @@ class X86System(System): class LinuxX86System(X86System): type = 'LinuxX86System' + + e820_table = Param.X86E820Table( + X86E820Table(), 'E820 map of physical memory') diff --git a/src/arch/x86/bios/E820.py b/src/arch/x86/bios/E820.py new file mode 100644 index 000000000..e161cd56f --- /dev/null +++ b/src/arch/x86/bios/E820.py @@ -0,0 +1,73 @@ +# Copyright (c) 2008 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use of this software in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# +# The software must be used only for Non-Commercial Use which means any +# use which is NOT directed to receiving any direct monetary +# compensation for, or commercial advantage from such use. Illustrative +# examples of non-commercial use are academic research, personal study, +# teaching, education and corporate research & development. +# Illustrative examples of commercial use are distributing products for +# commercial advantage and providing services using the software for +# commercial advantage. +# +# If you wish to use this software or functionality therein that may be +# covered by patents for commercial use, please contact: +# Director of Intellectual Property Licensing +# Office of Strategy and Technology +# Hewlett-Packard Company +# 1501 Page Mill Road +# Palo Alto, California 94304 +# +# Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. Redistributions +# in binary form must reproduce the above copyright notice, this list of +# conditions and the following disclaimer in the documentation and/or +# other materials provided with the distribution. Neither the name of +# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. No right of +# sublicense is granted herewith. Derivatives of the software and +# output created using the software may be prepared, but only for +# Non-Commercial Uses. Derivatives of the software may be shared with +# others provided: (i) the others agree to abide by the list of +# conditions herein which includes the Non-Commercial Use restrictions; +# and (ii) such Derivatives of the software include the above copyright +# notice to acknowledge the contribution from this software where +# applicable, this list of conditions and the disclaimer below. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Gabe Black + +from m5.params import * +from m5.SimObject import SimObject + +class X86E820Entry(SimObject): + type = 'X86E820Entry' + cxx_namespace = 'X86ISA' + cxx_class = 'E820Entry' + + addr = Param.Addr(0, 'address of the beginning of the region') + size = Param.MemorySize('0B', 'size of the region') + range_type = Param.UInt64('type of the region') + +class X86E820Table(SimObject): + type = 'X86E820Table' + cxx_namespace = 'X86ISA' + cxx_class = 'E820Table' + + entries = VectorParam.X86E820Entry([], 'entries for the e820 table') diff --git a/src/arch/x86/bios/e820.cc b/src/arch/x86/bios/e820.cc new file mode 100644 index 000000000..47adb703a --- /dev/null +++ b/src/arch/x86/bios/e820.cc @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2008 The Hewlett-Packard Development Company + * All rights reserved. + * + * Redistribution and use of this software in source and binary forms, + * with or without modification, are permitted provided that the + * following conditions are met: + * + * The software must be used only for Non-Commercial Use which means any + * use which is NOT directed to receiving any direct monetary + * compensation for, or commercial advantage from such use. Illustrative + * examples of non-commercial use are academic research, personal study, + * teaching, education and corporate research & development. + * Illustrative examples of commercial use are distributing products for + * commercial advantage and providing services using the software for + * commercial advantage. + * + * If you wish to use this software or functionality therein that may be + * covered by patents for commercial use, please contact: + * Director of Intellectual Property Licensing + * Office of Strategy and Technology + * Hewlett-Packard Company + * 1501 Page Mill Road + * Palo Alto, California 94304 + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. Redistributions + * in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. Neither the name of + * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. No right of + * sublicense is granted herewith. Derivatives of the software and + * output created using the software may be prepared, but only for + * Non-Commercial Uses. Derivatives of the software may be shared with + * others provided: (i) the others agree to abide by the list of + * conditions herein which includes the Non-Commercial Use restrictions; + * and (ii) such Derivatives of the software include the above copyright + * notice to acknowledge the contribution from this software where + * applicable, this list of conditions and the disclaimer below. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#include "arch/x86/bios/e820.hh" +#include "arch/x86/isa_traits.hh" +#include "mem/port.hh" +#include "sim/byteswap.hh" + +using namespace std; +using namespace X86ISA; + +template +void writeVal(T val, Port * port, Addr &addr) +{ + T guestVal = htog(val); + port->writeBlob(addr, (uint8_t *)&guestVal, sizeof(T)); + addr += sizeof(T); +} + +void X86ISA::E820Table::writeTo(Port * port, Addr countAddr, Addr addr) +{ + uint8_t e820Nr = entries.size(); + + // Make sure the number of entries isn't bigger than what the kernel + // would be capable of handling. + assert(e820Nr <= 128); + + uint8_t guestE820Nr = htog(e820Nr); + + port->writeBlob(countAddr, (uint8_t *)&guestE820Nr, sizeof(guestE820Nr)); + + for (int i = 0; i < e820Nr; i++) { + writeVal(entries[i]->addr, port, addr); + writeVal(entries[i]->size, port, addr); + writeVal(entries[i]->type, port, addr); + } +} + +E820Table * +X86E820TableParams::create() +{ + return new E820Table(this); +} + +E820Entry * +X86E820EntryParams::create() +{ + return new E820Entry(this); +} diff --git a/src/arch/x86/bios/e820.hh b/src/arch/x86/bios/e820.hh new file mode 100644 index 000000000..da738343b --- /dev/null +++ b/src/arch/x86/bios/e820.hh @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2008 The Hewlett-Packard Development Company + * All rights reserved. + * + * Redistribution and use of this software in source and binary forms, + * with or without modification, are permitted provided that the + * following conditions are met: + * + * The software must be used only for Non-Commercial Use which means any + * use which is NOT directed to receiving any direct monetary + * compensation for, or commercial advantage from such use. Illustrative + * examples of non-commercial use are academic research, personal study, + * teaching, education and corporate research & development. + * Illustrative examples of commercial use are distributing products for + * commercial advantage and providing services using the software for + * commercial advantage. + * + * If you wish to use this software or functionality therein that may be + * covered by patents for commercial use, please contact: + * Director of Intellectual Property Licensing + * Office of Strategy and Technology + * Hewlett-Packard Company + * 1501 Page Mill Road + * Palo Alto, California 94304 + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. Redistributions + * in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. Neither the name of + * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. No right of + * sublicense is granted herewith. Derivatives of the software and + * output created using the software may be prepared, but only for + * Non-Commercial Uses. Derivatives of the software may be shared with + * others provided: (i) the others agree to abide by the list of + * conditions herein which includes the Non-Commercial Use restrictions; + * and (ii) such Derivatives of the software include the above copyright + * notice to acknowledge the contribution from this software where + * applicable, this list of conditions and the disclaimer below. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef __ARCH_X86_BIOS_E820_HH__ +#define __ARCH_X86_BIOS_E820_HH__ + +#include "params/X86E820Entry.hh" +#include "params/X86E820Table.hh" +#include "sim/host.hh" +#include "sim/sim_object.hh" + +#include + +class Port; + +namespace X86ISA +{ + class E820Entry : public SimObject + { + public: + Addr addr; + Addr size; + uint32_t type; + + public: + typedef X86E820EntryParams Params; + E820Entry(Params *p) : + SimObject(p), addr(p->addr), size(p->size), type(p->range_type) + {} + }; + + class E820Table : public SimObject + { + public: + std::vector entries; + + public: + typedef X86E820TableParams Params; + E820Table(Params *p) : SimObject(p), entries(p->entries) + {} + + void writeTo(Port * port, Addr countAddr, Addr addr); + }; +}; + +#endif // __ARCH_X86_BIOS_E820_HH__ diff --git a/src/arch/x86/linux/system.cc b/src/arch/x86/linux/system.cc index 944bb2930..c2d9cb35c 100644 --- a/src/arch/x86/linux/system.cc +++ b/src/arch/x86/linux/system.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 The Hewlett-Packard Development Company + * Copyright (c) 2007-2008 The Hewlett-Packard Development Company * All rights reserved. * * Redistribution and use of this software in source and binary forms, @@ -68,7 +68,7 @@ using namespace LittleEndianGuest; using namespace X86ISA; LinuxX86System::LinuxX86System(Params *p) - : X86System(p), commandLine(p->boot_osflags) + : X86System(p), commandLine(p->boot_osflags), e820Table(p->e820_table) { } @@ -144,62 +144,7 @@ LinuxX86System::startup() // A pointer to the buffer for E820 entries. const Addr e820MapPointer = realModeData + 0x2d0; - struct e820Entry - { - Addr addr; - Addr size; - uint32_t type; - }; - - // The size is computed this way to ensure no padding sneaks in. - int e820EntrySize = - sizeof(e820Entry().addr) + - sizeof(e820Entry().size) + - sizeof(e820Entry().type); - - // I'm not sure what these should actually be. On a real machine they - // would be generated by the BIOS, and they need to reflect the regions - // which are actually available/reserved. These values are copied from - // my development machine. - e820Entry e820Map[] = { - {ULL(0x0), ULL(0x9d400), 1}, - {ULL(0x9d400), ULL(0xa0000) - ULL(0x9d400), 2}, - {ULL(0xe8000), ULL(0x100000) - ULL(0xe8000), 2}, - {ULL(0x100000), ULL(0xcfff9300) - ULL(0x100000), 1}, - {ULL(0xcfff9300), ULL(0xd0000000) - ULL(0xcfff9300), 2}, - {ULL(0xfec00000), ULL(0x100000000) - ULL(0xfec00000), 2} - }; - - uint8_t e820Nr = sizeof(e820Map) / sizeof(e820Entry); - - // Make sure the number of entries isn't bigger than what the kernel - // would be capable of providing. - assert(e820Nr <= 128); - - uint8_t guestE820Nr = X86ISA::htog(e820Nr); - physPort->writeBlob(e820MapNrPointer, - (uint8_t *)&guestE820Nr, sizeof(guestE820Nr)); - - for (int i = 0; i < e820Nr; i++) { - e820Entry guestE820Entry; - guestE820Entry.addr = X86ISA::htog(e820Map[i].addr); - guestE820Entry.size = X86ISA::htog(e820Map[i].size); - guestE820Entry.type = X86ISA::htog(e820Map[i].type); - physPort->writeBlob(e820MapPointer + e820EntrySize * i, - (uint8_t *)&guestE820Entry.addr, - sizeof(guestE820Entry.addr)); - physPort->writeBlob( - e820MapPointer + e820EntrySize * i + - sizeof(guestE820Entry.addr), - (uint8_t *)&guestE820Entry.size, - sizeof(guestE820Entry.size)); - physPort->writeBlob( - e820MapPointer + e820EntrySize * i + - sizeof(guestE820Entry.addr) + - sizeof(guestE820Entry.size), - (uint8_t *)&guestE820Entry.type, - sizeof(guestE820Entry.type)); - } + e820Table->writeTo(physPort, e820MapNrPointer, e820MapPointer); /* * Pass the location of the real mode data structure to the kernel diff --git a/src/arch/x86/linux/system.hh b/src/arch/x86/linux/system.hh index fc725ad45..a9c5f4ca9 100644 --- a/src/arch/x86/linux/system.hh +++ b/src/arch/x86/linux/system.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 The Hewlett-Packard Development Company + * Copyright (c) 2007-2008 The Hewlett-Packard Development Company * All rights reserved. * * Redistribution and use of this software in source and binary forms, @@ -62,12 +62,14 @@ #include #include "params/LinuxX86System.hh" +#include "arch/x86/bios/e820.hh" #include "arch/x86/system.hh" class LinuxX86System : public X86System { protected: std::string commandLine; + X86ISA::E820Table * e820Table; public: typedef LinuxX86SystemParams Params; -- cgit v1.2.3 From 5b5875341cb7d86ad7ce497666f0af526158775f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 12 Jun 2008 01:00:19 -0400 Subject: X86: Make the cpuid processor identifier return a real string. --- .../insts/general_purpose/processor_information.py | 29 ++++++++++------------ 1 file changed, 13 insertions(+), 16 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/processor_information.py b/src/arch/x86/isa/insts/general_purpose/processor_information.py index 6070169ac..4b73789af 100644 --- a/src/arch/x86/isa/insts/general_purpose/processor_information.py +++ b/src/arch/x86/isa/insts/general_purpose/processor_information.py @@ -1,4 +1,4 @@ -# Copyright (c) 2007 The Hewlett-Packard Development Company +# Copyright (c) 2007-2008 The Hewlett-Packard Development Company # All rights reserved. # # Redistribution and use of this software in source and binary forms, @@ -149,33 +149,30 @@ extendedStart: fault "NoFault" # 0x80000002 -- Processor Name String Identifier - # JUNK VALUES - limm rax, 0x80000018, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 + limm rax, 0x656B6146, dataSize=4 + limm rbx, 0x20354D20, dataSize=4 + limm rcx, 0x5F363878, dataSize=4 + limm rdx, 0x43203436, dataSize=4 bri t0, label("end") fault "NoFault" fault "NoFault" fault "NoFault" # 0x80000003 -- Processor Name String Identifier - # JUNK VALUES - limm rax, 0x80000018, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 + limm rax, 0x00005550, dataSize=4 + limm rbx, 0x00000000, dataSize=4 + limm rdx, 0x00000000, dataSize=4 + limm rcx, 0x00000000, dataSize=4 bri t0, label("end") fault "NoFault" fault "NoFault" fault "NoFault" # 0x80000004 -- Processor Name String Identifier - # JUNK VALUES - limm rax, 0x80000018, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 + limm rax, 0x00000000, dataSize=4 + limm rbx, 0x00000000, dataSize=4 + limm rdx, 0x00000000, dataSize=4 + limm rcx, 0x00000000, dataSize=4 bri t0, label("end") fault "NoFault" fault "NoFault" -- cgit v1.2.3 From ce43e46576ccf09d56aeb7021d3decd75d08d90c Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 14 Jun 2008 12:57:21 -0700 Subject: Fix various SWIG warnings --- src/arch/mips/MipsTLB.py | 4 +--- src/arch/x86/X86TLB.py | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'src/arch') diff --git a/src/arch/mips/MipsTLB.py b/src/arch/mips/MipsTLB.py index ce8847365..1d0244e22 100644 --- a/src/arch/mips/MipsTLB.py +++ b/src/arch/mips/MipsTLB.py @@ -33,10 +33,8 @@ from m5.SimObject import SimObject from m5.params import * class MipsTLB(SimObject): - abstract = True type = 'MipsTLB' - cxx_namespace = 'MipsISA' - cxx_class = 'TLB' + abstract = True size = Param.Int("TLB size") class MipsDTB(MipsTLB): diff --git a/src/arch/x86/X86TLB.py b/src/arch/x86/X86TLB.py index dc080f37e..8dd53620e 100644 --- a/src/arch/x86/X86TLB.py +++ b/src/arch/x86/X86TLB.py @@ -69,8 +69,6 @@ if build_env['FULL_SYSTEM']: class X86TLB(SimObject): type = 'X86TLB' - cxx_namespace = 'X86ISA' - cxx_class = 'TLB' abstract = True size = Param.Int("TLB size") if build_env['FULL_SYSTEM']: -- cgit v1.2.3 From c5fbbf376a6be4bb3ad7ddc64841450541c16db6 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 1 Jul 2008 10:24:19 -0400 Subject: Change everything to use the cached virtPort rather than created their own each time. This appears to work, but I don't want to commit it until it gets tested a lot more. I haven't deleted the functionality in this patch that will come later, but one question is how to enforce encourage objects that call getVirtPort() to not cache the virtual port since if the CPU changes out from under them it will be worse than useless. Perhaps a null function like delVirtPort() is still useful in that case. --- src/arch/alpha/utility.cc | 2 +- src/arch/mips/utility.cc | 2 +- src/arch/sparc/utility.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/utility.cc b/src/arch/alpha/utility.cc index f1864203b..94e82adf3 100644 --- a/src/arch/alpha/utility.cc +++ b/src/arch/alpha/utility.cc @@ -49,7 +49,7 @@ uint64_t getArgument(ThreadContext *tc, int number, bool fp) return tc->readIntReg(ArgumentReg[number]); } else { Addr sp = tc->readIntReg(StackPointerReg); - VirtualPort *vp = tc->getVirtPort(tc); + VirtualPort *vp = tc->getVirtPort(); uint64_t arg = vp->read(sp + (number-NumArgumentRegs) * sizeof(uint64_t)); tc->delVirtPort(vp); diff --git a/src/arch/mips/utility.cc b/src/arch/mips/utility.cc index c254811fa..52c52f8e7 100644 --- a/src/arch/mips/utility.cc +++ b/src/arch/mips/utility.cc @@ -59,7 +59,7 @@ getArgument(ThreadContext *tc, int number, bool fp) return tc->readIntReg(ArgumentReg[number]); } else { Addr sp = tc->readIntReg(StackPointerReg); - VirtualPort *vp = tc->getVirtPort(tc); + VirtualPort *vp = tc->getVirtPort(); uint64_t arg = vp->read(sp + (number-NumArgumentRegs) * sizeof(uint64_t)); tc->delVirtPort(vp); diff --git a/src/arch/sparc/utility.cc b/src/arch/sparc/utility.cc index 6d4358603..0677823af 100644 --- a/src/arch/sparc/utility.cc +++ b/src/arch/sparc/utility.cc @@ -50,7 +50,7 @@ uint64_t getArgument(ThreadContext *tc, int number, bool fp) { return tc->readIntReg(ArgumentReg[number]); } else { Addr sp = tc->readIntReg(StackPointerReg); - VirtualPort *vp = tc->getVirtPort(tc); + VirtualPort *vp = tc->getVirtPort(); uint64_t arg = vp->read(sp + 92 + (number-NumArgumentRegs) * sizeof(uint64_t)); tc->delVirtPort(vp); -- cgit v1.2.3 From a4a7a09e9622d6ad1ca91a4df253b9768c73de90 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Tue, 1 Jul 2008 10:25:07 -0400 Subject: Remove delVirtPort() and make getVirtPort() only return cached version. --- src/arch/alpha/linux/system.cc | 1 - src/arch/alpha/stacktrace.cc | 4 ---- src/arch/alpha/utility.cc | 1 - src/arch/mips/linux/system.cc | 1 - src/arch/mips/stacktrace.cc | 4 ---- src/arch/mips/utility.cc | 1 - src/arch/sparc/stacktrace.cc | 4 ---- src/arch/sparc/utility.cc | 1 - src/arch/x86/stacktrace.cc | 4 ---- 9 files changed, 21 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/linux/system.cc b/src/arch/alpha/linux/system.cc index 102598716..a52bcae36 100644 --- a/src/arch/alpha/linux/system.cc +++ b/src/arch/alpha/linux/system.cc @@ -169,7 +169,6 @@ LinuxAlphaSystem::setDelayLoop(ThreadContext *tc) vp = tc->getVirtPort(); vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988)); - tc->delVirtPort(vp); } } diff --git a/src/arch/alpha/stacktrace.cc b/src/arch/alpha/stacktrace.cc index c16498e72..124949781 100644 --- a/src/arch/alpha/stacktrace.cc +++ b/src/arch/alpha/stacktrace.cc @@ -71,8 +71,6 @@ namespace AlphaISA if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr)) panic("thread info not compiled into kernel\n"); name_off = vp->readGtoH(addr); - - tc->delVirtPort(vp); } Addr @@ -88,7 +86,6 @@ namespace AlphaISA vp = tc->getVirtPort(); tsk = vp->readGtoH(base + task_off); - tc->delVirtPort(vp); return tsk; } @@ -106,7 +103,6 @@ namespace AlphaISA vp = tc->getVirtPort(); pd = vp->readGtoH(task + pid_off); - tc->delVirtPort(vp); return pd; } diff --git a/src/arch/alpha/utility.cc b/src/arch/alpha/utility.cc index 94e82adf3..23abceb93 100644 --- a/src/arch/alpha/utility.cc +++ b/src/arch/alpha/utility.cc @@ -52,7 +52,6 @@ uint64_t getArgument(ThreadContext *tc, int number, bool fp) VirtualPort *vp = tc->getVirtPort(); uint64_t arg = vp->read(sp + (number-NumArgumentRegs) * sizeof(uint64_t)); - tc->delVirtPort(vp); return arg; } #else diff --git a/src/arch/mips/linux/system.cc b/src/arch/mips/linux/system.cc index bed863e9d..23062c96b 100644 --- a/src/arch/mips/linux/system.cc +++ b/src/arch/mips/linux/system.cc @@ -168,7 +168,6 @@ LinuxMipsSystem::setDelayLoop(ThreadContext *tc) vp = tc->getVirtPort(); vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988)); - tc->delVirtPort(vp); } } diff --git a/src/arch/mips/stacktrace.cc b/src/arch/mips/stacktrace.cc index 6c6f6bb3c..482d264e8 100644 --- a/src/arch/mips/stacktrace.cc +++ b/src/arch/mips/stacktrace.cc @@ -70,8 +70,6 @@ ProcessInfo::ProcessInfo(ThreadContext *_tc) // if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr)) // panic("thread info not compiled into kernel\n"); // name_off = vp->readGtoH(addr); - - tc->delVirtPort(vp); } Addr @@ -87,7 +85,6 @@ ProcessInfo::task(Addr ksp) const vp = tc->getVirtPort(); tsk = vp->readGtoH(base + task_off); - tc->delVirtPort(vp); return tsk; } @@ -105,7 +102,6 @@ ProcessInfo::pid(Addr ksp) const vp = tc->getVirtPort(); pd = vp->readGtoH(task + pid_off); - tc->delVirtPort(vp); return pd; } diff --git a/src/arch/mips/utility.cc b/src/arch/mips/utility.cc index 52c52f8e7..36cf76c67 100644 --- a/src/arch/mips/utility.cc +++ b/src/arch/mips/utility.cc @@ -62,7 +62,6 @@ getArgument(ThreadContext *tc, int number, bool fp) VirtualPort *vp = tc->getVirtPort(); uint64_t arg = vp->read(sp + (number-NumArgumentRegs) * sizeof(uint64_t)); - tc->delVirtPort(vp); return arg; } #else diff --git a/src/arch/sparc/stacktrace.cc b/src/arch/sparc/stacktrace.cc index 2d7991267..8ec1d36c8 100644 --- a/src/arch/sparc/stacktrace.cc +++ b/src/arch/sparc/stacktrace.cc @@ -70,8 +70,6 @@ namespace SparcISA if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr)) panic("thread info not compiled into kernel\n"); name_off = vp->readGtoH(addr); - - tc->delVirtPort(vp); } Addr @@ -87,7 +85,6 @@ namespace SparcISA vp = tc->getVirtPort(); tsk = vp->readGtoH(base + task_off); - tc->delVirtPort(vp); return tsk; } @@ -105,7 +102,6 @@ namespace SparcISA vp = tc->getVirtPort(); pd = vp->readGtoH(task + pid_off); - tc->delVirtPort(vp); return pd; } diff --git a/src/arch/sparc/utility.cc b/src/arch/sparc/utility.cc index 0677823af..8f5c3e036 100644 --- a/src/arch/sparc/utility.cc +++ b/src/arch/sparc/utility.cc @@ -53,7 +53,6 @@ uint64_t getArgument(ThreadContext *tc, int number, bool fp) { VirtualPort *vp = tc->getVirtPort(); uint64_t arg = vp->read(sp + 92 + (number-NumArgumentRegs) * sizeof(uint64_t)); - tc->delVirtPort(vp); return arg; } #else diff --git a/src/arch/x86/stacktrace.cc b/src/arch/x86/stacktrace.cc index 300e8dcd0..87767583b 100644 --- a/src/arch/x86/stacktrace.cc +++ b/src/arch/x86/stacktrace.cc @@ -70,8 +70,6 @@ namespace X86ISA if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr)) panic("thread info not compiled into kernel\n"); name_off = vp->readGtoH(addr); - - tc->delVirtPort(vp); } Addr @@ -87,7 +85,6 @@ namespace X86ISA vp = tc->getVirtPort(); tsk = vp->readGtoH(base + task_off); - tc->delVirtPort(vp); return tsk; } @@ -105,7 +102,6 @@ namespace X86ISA vp = tc->getVirtPort(); pd = vp->readGtoH(task + pid_off); - tc->delVirtPort(vp); return pd; } -- cgit v1.2.3 From f9a597ddf307246b1aee915b59de503d2850ccce Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 11 Jul 2008 08:52:50 -0700 Subject: m5ops: clean up the m5ops stuff. - insert warnings for deprecated m5ops - reserve opcodes for Ali's stuff - remove code for stuff that has been deprecated forever - simplify m5op_alpha --- src/arch/alpha/isa/decoder.isa | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index 2177e8c4f..dc30039b2 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -806,14 +806,15 @@ decode OPCODE default Unknown::unknown() { 0x04: quiesceTime({{ R0 = PseudoInst::quiesceTime(xc->tcBase()); }}, IsNonSpeculative, IsUnverifiable); - 0x10: ivlb({{ - warn_once("Obsolete M5 instruction ivlb encountered.\n"); + 0x10: deprecated_ivlb({{ + warn_once("Obsolete M5 ivlb instruction encountered.\n"); }}); - 0x11: ivle({{ - warn_once("Obsolete M5 instruction ivlb encountered.\n"); + 0x11: deprecated_ivle({{ + warn_once("Obsolete M5 ivlb instruction encountered.\n"); }}); - 0x20: m5exit_old({{ - PseudoInst::m5exit_old(xc->tcBase()); + 0x20: deprecated_exit ({{ + warn_once("deprecated M5 exit instruction encountered.\n"); + PseudoInst::m5exit(xc->tcBase(), 0); }}, No_OpClass, IsNonSpeculative); 0x21: m5exit({{ PseudoInst::m5exit(xc->tcBase(), R16); @@ -821,7 +822,9 @@ decode OPCODE default Unknown::unknown() { 0x31: loadsymbol({{ PseudoInst::loadsymbol(xc->tcBase()); }}, No_OpClass, IsNonSpeculative); - 0x30: initparam({{ Ra = xc->tcBase()->getCpuPtr()->system->init_param; }}); + 0x30: initparam({{ + Ra = xc->tcBase()->getCpuPtr()->system->init_param; + }}); 0x40: resetstats({{ PseudoInst::resetstats(xc->tcBase(), R16, R17); }}, IsNonSpeculative); @@ -849,11 +852,20 @@ decode OPCODE default Unknown::unknown() { 0x54: m5panic({{ panic("M5 panic instruction called at pc=%#x.", xc->readPC()); }}, IsNonSpeculative); - 0x55: m5anBegin({{ - PseudoInst::anBegin(xc->tcBase(), R16); + 0x55: m5reserved1({{ + warn("M5 reserved opcode ignored"); + }}, IsNonSpeculative); + 0x56: m5reserved2({{ + warn("M5 reserved opcode ignored"); + }}, IsNonSpeculative); + 0x57: m5reserved3({{ + warn("M5 reserved opcode ignored"); + }}, IsNonSpeculative); + 0x58: m5reserved4({{ + warn("M5 reserved opcode ignored"); }}, IsNonSpeculative); - 0x56: m5anWait({{ - PseudoInst::anWait(xc->tcBase(), R16, R17); + 0x59: m5reserved5({{ + warn("M5 reserved opcode ignored"); }}, IsNonSpeculative); } } -- cgit v1.2.3 From 2cd04fd6da67d874fd4e563ed05707a42ff0598f Mon Sep 17 00:00:00 2001 From: Michael Adler Date: Wed, 23 Jul 2008 14:41:33 -0700 Subject: syscalls: Add a bunch of missing system calls. readlink, umask, truncate, ftruncate, mkdir, and getcwd. --- src/arch/alpha/linux/process.cc | 12 ++++++------ src/arch/alpha/tru64/process.cc | 6 +++--- src/arch/mips/linux/process.cc | 8 ++++---- src/arch/sparc/linux/syscalls.cc | 10 +++++----- src/arch/sparc/solaris/process.cc | 4 ++-- 5 files changed, 20 insertions(+), 20 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc index ec47992bd..0a9d2f1a3 100644 --- a/src/arch/alpha/linux/process.cc +++ b/src/arch/alpha/linux/process.cc @@ -179,9 +179,9 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 55 */ SyscallDesc("osf_reboot", unimplementedFunc), /* 56 */ SyscallDesc("osf_revoke", unimplementedFunc), /* 57 */ SyscallDesc("symlink", unimplementedFunc), - /* 58 */ SyscallDesc("readlink", unimplementedFunc), + /* 58 */ SyscallDesc("readlink", readlinkFunc), /* 59 */ SyscallDesc("execve", unimplementedFunc), - /* 60 */ SyscallDesc("umask", unimplementedFunc), + /* 60 */ SyscallDesc("umask", umaskFunc), /* 61 */ SyscallDesc("chroot", unimplementedFunc), /* 62 */ SyscallDesc("osf_old_fstat", unimplementedFunc), /* 63 */ SyscallDesc("getpgrp", unimplementedFunc), @@ -250,14 +250,14 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 126 */ SyscallDesc("setreuid", unimplementedFunc), /* 127 */ SyscallDesc("setregid", unimplementedFunc), /* 128 */ SyscallDesc("rename", renameFunc), - /* 129 */ SyscallDesc("truncate", unimplementedFunc), - /* 130 */ SyscallDesc("ftruncate", unimplementedFunc), + /* 129 */ SyscallDesc("truncate", truncateFunc), + /* 130 */ SyscallDesc("ftruncate", ftruncateFunc), /* 131 */ SyscallDesc("flock", unimplementedFunc), /* 132 */ SyscallDesc("setgid", unimplementedFunc), /* 133 */ SyscallDesc("sendto", unimplementedFunc), /* 134 */ SyscallDesc("shutdown", unimplementedFunc), /* 135 */ SyscallDesc("socketpair", unimplementedFunc), - /* 136 */ SyscallDesc("mkdir", unimplementedFunc), + /* 136 */ SyscallDesc("mkdir", mkdirFunc), /* 137 */ SyscallDesc("rmdir", unimplementedFunc), /* 138 */ SyscallDesc("osf_utimes", unimplementedFunc), /* 139 */ SyscallDesc("osf_old_sigreturn", unimplementedFunc), @@ -491,7 +491,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 364 */ SyscallDesc("getrusage", getrusageFunc), /* 365 */ SyscallDesc("wait4", unimplementedFunc), /* 366 */ SyscallDesc("adjtimex", unimplementedFunc), - /* 367 */ SyscallDesc("getcwd", unimplementedFunc), + /* 367 */ SyscallDesc("getcwd", getcwdFunc), /* 368 */ SyscallDesc("capget", unimplementedFunc), /* 369 */ SyscallDesc("capset", unimplementedFunc), /* 370 */ SyscallDesc("sendfile", unimplementedFunc), diff --git a/src/arch/alpha/tru64/process.cc b/src/arch/alpha/tru64/process.cc index 6823d820a..e9f7b6be1 100644 --- a/src/arch/alpha/tru64/process.cc +++ b/src/arch/alpha/tru64/process.cc @@ -260,9 +260,9 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { /* 55 */ SyscallDesc("reboot", unimplementedFunc), /* 56 */ SyscallDesc("revoke", unimplementedFunc), /* 57 */ SyscallDesc("symlink", unimplementedFunc), - /* 58 */ SyscallDesc("readlink", unimplementedFunc), + /* 58 */ SyscallDesc("readlink", readlinkFunc), /* 59 */ SyscallDesc("execve", unimplementedFunc), - /* 60 */ SyscallDesc("umask", unimplementedFunc), + /* 60 */ SyscallDesc("umask", umaskFunc), /* 61 */ SyscallDesc("chroot", unimplementedFunc), /* 62 */ SyscallDesc("old_fstat", unimplementedFunc), /* 63 */ SyscallDesc("getpgrp", unimplementedFunc), @@ -339,7 +339,7 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { /* 133 */ SyscallDesc("sendto", unimplementedFunc), /* 134 */ SyscallDesc("shutdown", unimplementedFunc), /* 135 */ SyscallDesc("socketpair", unimplementedFunc), - /* 136 */ SyscallDesc("mkdir", unimplementedFunc), + /* 136 */ SyscallDesc("mkdir", mkdirFunc), /* 137 */ SyscallDesc("rmdir", unimplementedFunc), /* 138 */ SyscallDesc("utimes", unimplementedFunc), /* 139 */ SyscallDesc("obsolete 4.2 sigreturn", unimplementedFunc), diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc index 06e6e2cf4..8a13d0f18 100644 --- a/src/arch/mips/linux/process.cc +++ b/src/arch/mips/linux/process.cc @@ -160,7 +160,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 36 */ SyscallDesc("sync", unimplementedFunc), /* 37 */ SyscallDesc("kill", unimplementedFunc), /* 38 */ SyscallDesc("rename", unimplementedFunc), - /* 39 */ SyscallDesc("mkdir", unimplementedFunc), + /* 39 */ SyscallDesc("mkdir", mkdirFunc), /* 40 */ SyscallDesc("rmdir", unimplementedFunc), /* 41 */ SyscallDesc("dup", unimplementedFunc), /* 42 */ SyscallDesc("pipe", pipePseudoFunc), @@ -181,7 +181,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 57 */ SyscallDesc("setpgid", unimplementedFunc), /* 58 */ SyscallDesc("ulimit", unimplementedFunc), /* 59 */ SyscallDesc("unused#59", unimplementedFunc), - /* 60 */ SyscallDesc("umask", unimplementedFunc), + /* 60 */ SyscallDesc("umask", umaskFunc), /* 61 */ SyscallDesc("chroot", unimplementedFunc), /* 62 */ SyscallDesc("ustat", unimplementedFunc), /* 63 */ SyscallDesc("dup2", unimplementedFunc), @@ -206,7 +206,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 82 */ SyscallDesc("reserved#82", unimplementedFunc), /* 83 */ SyscallDesc("symlink", unimplementedFunc), /* 84 */ SyscallDesc("unused#84", unimplementedFunc), - /* 85 */ SyscallDesc("readlink", unimplementedFunc), + /* 85 */ SyscallDesc("readlink", readlinkFunc), /* 86 */ SyscallDesc("uselib", unimplementedFunc), /* 87 */ SyscallDesc("swapon", gethostnameFunc), /* 88 */ SyscallDesc("reboot", unimplementedFunc), @@ -324,7 +324,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 200 */ SyscallDesc("pread64", unimplementedFunc), /* 201 */ SyscallDesc("pwrite64", unimplementedFunc), /* 202 */ SyscallDesc("chown", unimplementedFunc), - /* 203 */ SyscallDesc("getcwd", unimplementedFunc), + /* 203 */ SyscallDesc("getcwd", getcwdFunc), /* 204 */ SyscallDesc("capget", unimplementedFunc), /* 205 */ SyscallDesc("capset", unimplementedFunc), /* 206 */ SyscallDesc("sigalstack", unimplementedFunc), diff --git a/src/arch/sparc/linux/syscalls.cc b/src/arch/sparc/linux/syscalls.cc index 03c8bafe2..2964b3c1a 100644 --- a/src/arch/sparc/linux/syscalls.cc +++ b/src/arch/sparc/linux/syscalls.cc @@ -147,7 +147,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = { /* 55 */ SyscallDesc("reboot", unimplementedFunc), //32 bit /* 56 */ SyscallDesc("mmap2", unimplementedFunc), //32 bit /* 57 */ SyscallDesc("symlink", unimplementedFunc), - /* 58 */ SyscallDesc("readlink", unimplementedFunc), //32 bit + /* 58 */ SyscallDesc("readlink", readlinkFunc), //32 bit /* 59 */ SyscallDesc("execve", unimplementedFunc), //32 bit /* 60 */ SyscallDesc("umask", unimplementedFunc), //32 bit /* 61 */ SyscallDesc("chroot", unimplementedFunc), @@ -208,7 +208,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = { /* 116 */ SyscallDesc("gettimeofday", unimplementedFunc), //32 bit /* 117 */ SyscallDesc("getrusage", unimplementedFunc), //32 bit /* 118 */ SyscallDesc("getsockopt", unimplementedFunc), - /* 119 */ SyscallDesc("getcwd", unimplementedFunc), + /* 119 */ SyscallDesc("getcwd", getcwdFunc), /* 120 */ SyscallDesc("readv", unimplementedFunc), /* 121 */ SyscallDesc("writev", unimplementedFunc), /* 122 */ SyscallDesc("settimeofday", unimplementedFunc), //32 bit @@ -225,7 +225,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = { /* 133 */ SyscallDesc("sendto", unimplementedFunc), /* 134 */ SyscallDesc("shutdown", unimplementedFunc), /* 135 */ SyscallDesc("socketpair", unimplementedFunc), - /* 136 */ SyscallDesc("mkdir", unimplementedFunc), //32 bit + /* 136 */ SyscallDesc("mkdir", mkdirFunc), //32 bit /* 137 */ SyscallDesc("rmdir", unimplementedFunc), /* 138 */ SyscallDesc("utimes", unimplementedFunc), //32 bit /* 139 */ SyscallDesc("stat64", unimplementedFunc), @@ -450,7 +450,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = { /* 55 */ SyscallDesc("reboot", unimplementedFunc), /* 56 */ SyscallDesc("mmap2", unimplementedFunc), /* 57 */ SyscallDesc("symlink", unimplementedFunc), - /* 58 */ SyscallDesc("readlink", unimplementedFunc), + /* 58 */ SyscallDesc("readlink", readlinkFunc), /* 59 */ SyscallDesc("execve", unimplementedFunc), /* 60 */ SyscallDesc("umask", unimplementedFunc), /* 61 */ SyscallDesc("chroot", unimplementedFunc), @@ -528,7 +528,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = { /* 133 */ SyscallDesc("sendto", unimplementedFunc), /* 134 */ SyscallDesc("shutdown", unimplementedFunc), /* 135 */ SyscallDesc("socketpair", unimplementedFunc), - /* 136 */ SyscallDesc("mkdir", unimplementedFunc), + /* 136 */ SyscallDesc("mkdir", mkdirFunc), /* 137 */ SyscallDesc("rmdir", unimplementedFunc), /* 138 */ SyscallDesc("utimes", unimplementedFunc), /* 139 */ SyscallDesc("stat64", unimplementedFunc), diff --git a/src/arch/sparc/solaris/process.cc b/src/arch/sparc/solaris/process.cc index 40d172690..e0c3eaa4b 100644 --- a/src/arch/sparc/solaris/process.cc +++ b/src/arch/sparc/solaris/process.cc @@ -123,7 +123,7 @@ SyscallDesc SparcSolarisProcess::syscallDescs[] = { /* 57 */ SyscallDesc("utssys", unimplementedFunc), /* 58 */ SyscallDesc("fdsync", unimplementedFunc), /* 59 */ SyscallDesc("execve", unimplementedFunc), - /* 60 */ SyscallDesc("umask", unimplementedFunc), + /* 60 */ SyscallDesc("umask", umaskFunc), /* 61 */ SyscallDesc("chroot", unimplementedFunc), /* 62 */ SyscallDesc("fcntl", unimplementedFunc), /* 63 */ SyscallDesc("ulimit", unimplementedFunc), @@ -153,7 +153,7 @@ SyscallDesc SparcSolarisProcess::syscallDescs[] = { /* 87 */ SyscallDesc("poll", unimplementedFunc), /* 88 */ SyscallDesc("lstat", unimplementedFunc), /* 89 */ SyscallDesc("symlink", unimplementedFunc), - /* 90 */ SyscallDesc("readlink", unimplementedFunc), + /* 90 */ SyscallDesc("readlink", readlinkFunc), /* 91 */ SyscallDesc("setgroups", unimplementedFunc), /* 92 */ SyscallDesc("getgroups", unimplementedFunc), /* 93 */ SyscallDesc("fchmod", unimplementedFunc), -- cgit v1.2.3 From b179c3f4cd1e89872de34d70105f703e72377029 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 3 Aug 2008 14:43:24 -0700 Subject: X86: Make hint nops consume their modrm byte. --- src/arch/x86/predecoder_tables.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/predecoder_tables.cc b/src/arch/x86/predecoder_tables.cc index f8aff39f1..bcd5face6 100644 --- a/src/arch/x86/predecoder_tables.cc +++ b/src/arch/x86/predecoder_tables.cc @@ -123,7 +123,7 @@ namespace X86ISA { //LSB // MSB 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F /* 0 */ 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 1, -/* 1 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0, +/* 1 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1, /* 2 */ 1 , 1 , 1 , 1 , 1 , 0 , 1 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1, /* 3 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0, /* 4 */ 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1, -- cgit v1.2.3 From ee62a0fec8e63f45f816c61ab9fb28aba7414185 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 11 Aug 2008 12:22:16 -0700 Subject: params: Convert the CPU objects to use the auto generated param structs. A whole bunch of stuff has been converted to use the new params stuff, but the CPU wasn't one of them. While we're at it, make some things a bit more stylish. Most of the work was done by Gabe, I just cleaned stuff up a bit more at the end. --- src/arch/mips/regfile/misc_regfile.cc | 103 +++++++++++++++++----------------- 1 file changed, 53 insertions(+), 50 deletions(-) (limited to 'src/arch') diff --git a/src/arch/mips/regfile/misc_regfile.cc b/src/arch/mips/regfile/misc_regfile.cc index dc6ae0baf..407851007 100755 --- a/src/arch/mips/regfile/misc_regfile.cc +++ b/src/arch/mips/regfile/misc_regfile.cc @@ -40,6 +40,8 @@ #include "cpu/base.hh" #include "cpu/exetrace.hh" +#include "params/DerivO3CPU.hh" + using namespace std; std::string MiscRegFile::miscRegNames[NumMiscRegs] = @@ -170,11 +172,12 @@ void MiscRegFile::reset(std::string core_name, unsigned num_threads, unsigned num_vpes, BaseCPU *_cpu) { - DPRINTF(MipsPRA, "Resetting CP0 State with %i TCs and %i VPEs\n", num_threads, num_vpes); cpu = _cpu; - const BaseCPU::Params *p = _cpu->params; + + TheISA::CoreSpecific &cp = cpu->coreParams; + // Do Default CP0 initialization HERE // Do Initialization for MT cores here (eventually use @@ -183,10 +186,10 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads, DPRINTF(MipsPRA, "Initializing CP0 State.... "); MiscReg ProcID = readRegNoEffect(PRId); - replaceBits(ProcID,PRIdCoOp_HI,PRIdCoOp_LO,p->coreParams.CP0_PRId_CompanyOptions); - replaceBits(ProcID,PRIdCoID_HI,PRIdCoID_LO,p->coreParams.CP0_PRId_CompanyID); - replaceBits(ProcID,PRIdProc_ID_HI,PRIdProc_ID_LO,p->coreParams.CP0_PRId_ProcessorID); - replaceBits(ProcID,PRIdRev_HI,PRIdRev_LO,p->coreParams.CP0_PRId_Revision); + replaceBits(ProcID,PRIdCoOp_HI,PRIdCoOp_LO,cp.CP0_PRId_CompanyOptions); + replaceBits(ProcID,PRIdCoID_HI,PRIdCoID_LO,cp.CP0_PRId_CompanyID); + replaceBits(ProcID,PRIdProc_ID_HI,PRIdProc_ID_LO,cp.CP0_PRId_ProcessorID); + replaceBits(ProcID,PRIdRev_HI,PRIdRev_LO,cp.CP0_PRId_Revision); setRegNoEffect(PRId,ProcID); // Now, create Write Mask for ProcID register MiscReg ProcID_Mask = 0; // Read-Only register @@ -195,11 +198,11 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads, // Config MiscReg cfg = readRegNoEffect(Config); - replaceBits(cfg, Config_BE_HI, Config_BE_LO, p->coreParams.CP0_Config_BE); - replaceBits(cfg, Config_AT_HI, Config_AT_LO, p->coreParams.CP0_Config_AT); - replaceBits(cfg, Config_AR_HI, Config_AR_LO, p->coreParams.CP0_Config_AR); - replaceBits(cfg, Config_MT_HI, Config_MT_LO, p->coreParams.CP0_Config_MT); - replaceBits(cfg, Config_VI_HI, Config_VI_LO, p->coreParams.CP0_Config_VI); + replaceBits(cfg, Config_BE_HI, Config_BE_LO, cp.CP0_Config_BE); + replaceBits(cfg, Config_AT_HI, Config_AT_LO, cp.CP0_Config_AT); + replaceBits(cfg, Config_AR_HI, Config_AR_LO, cp.CP0_Config_AR); + replaceBits(cfg, Config_MT_HI, Config_MT_LO, cp.CP0_Config_MT); + replaceBits(cfg, Config_VI_HI, Config_VI_LO, cp.CP0_Config_VI); replaceBits(cfg, Config_M, 1); setRegNoEffect(Config, cfg); // Now, create Write Mask for Config register @@ -209,20 +212,20 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads, // Config1 MiscReg cfg1 = readRegNoEffect(Config1); - replaceBits(cfg1, Config1_MMUSize_HI, Config1_MMUSize_LO, p->coreParams.CP0_Config1_MMU); - replaceBits(cfg1, Config1_IS_HI, Config1_IS_LO, p->coreParams.CP0_Config1_IS); - replaceBits(cfg1, Config1_IL_HI, Config1_IL_LO, p->coreParams.CP0_Config1_IL); - replaceBits(cfg1, Config1_IA_HI, Config1_IA_LO, p->coreParams.CP0_Config1_IA); - replaceBits(cfg1, Config1_DS_HI, Config1_DS_LO, p->coreParams.CP0_Config1_DS); - replaceBits(cfg1, Config1_DL_HI, Config1_DL_LO, p->coreParams.CP0_Config1_DL); - replaceBits(cfg1, Config1_DA_HI, Config1_DA_LO, p->coreParams.CP0_Config1_DA); - replaceBits(cfg1, Config1_FP_HI, Config1_FP_LO, p->coreParams.CP0_Config1_FP); - replaceBits(cfg1, Config1_EP_HI, Config1_EP_LO, p->coreParams.CP0_Config1_EP); - replaceBits(cfg1, Config1_WR_HI, Config1_WR_LO, p->coreParams.CP0_Config1_WR); - replaceBits(cfg1, Config1_MD_HI, Config1_MD_LO, p->coreParams.CP0_Config1_MD); - replaceBits(cfg1, Config1_C2_HI, Config1_C2_LO, p->coreParams.CP0_Config1_C2); - replaceBits(cfg1, Config1_PC_HI, Config1_PC_LO, p->coreParams.CP0_Config1_PC); - replaceBits(cfg1, Config1_M, p->coreParams.CP0_Config1_M); + replaceBits(cfg1, Config1_MMUSize_HI, Config1_MMUSize_LO, cp.CP0_Config1_MMU); + replaceBits(cfg1, Config1_IS_HI, Config1_IS_LO, cp.CP0_Config1_IS); + replaceBits(cfg1, Config1_IL_HI, Config1_IL_LO, cp.CP0_Config1_IL); + replaceBits(cfg1, Config1_IA_HI, Config1_IA_LO, cp.CP0_Config1_IA); + replaceBits(cfg1, Config1_DS_HI, Config1_DS_LO, cp.CP0_Config1_DS); + replaceBits(cfg1, Config1_DL_HI, Config1_DL_LO, cp.CP0_Config1_DL); + replaceBits(cfg1, Config1_DA_HI, Config1_DA_LO, cp.CP0_Config1_DA); + replaceBits(cfg1, Config1_FP_HI, Config1_FP_LO, cp.CP0_Config1_FP); + replaceBits(cfg1, Config1_EP_HI, Config1_EP_LO, cp.CP0_Config1_EP); + replaceBits(cfg1, Config1_WR_HI, Config1_WR_LO, cp.CP0_Config1_WR); + replaceBits(cfg1, Config1_MD_HI, Config1_MD_LO, cp.CP0_Config1_MD); + replaceBits(cfg1, Config1_C2_HI, Config1_C2_LO, cp.CP0_Config1_C2); + replaceBits(cfg1, Config1_PC_HI, Config1_PC_LO, cp.CP0_Config1_PC); + replaceBits(cfg1, Config1_M, cp.CP0_Config1_M); setRegNoEffect(Config1, cfg1); // Now, create Write Mask for Config register MiscReg cfg1_Mask = 0; // Read Only Register @@ -231,15 +234,15 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads, // Config2 MiscReg cfg2 = readRegNoEffect(Config2); - replaceBits(cfg2, Config2_TU_HI, Config2_TU_LO, p->coreParams.CP0_Config2_TU); - replaceBits(cfg2, Config2_TS_HI, Config2_TS_LO, p->coreParams.CP0_Config2_TS); - replaceBits(cfg2, Config2_TL_HI, Config2_TL_LO, p->coreParams.CP0_Config2_TL); - replaceBits(cfg2, Config2_TA_HI, Config2_TA_LO, p->coreParams.CP0_Config2_TA); - replaceBits(cfg2, Config2_SU_HI, Config2_SU_LO, p->coreParams.CP0_Config2_SU); - replaceBits(cfg2, Config2_SS_HI, Config2_SS_LO, p->coreParams.CP0_Config2_SS); - replaceBits(cfg2, Config2_SL_HI, Config2_SL_LO, p->coreParams.CP0_Config2_SL); - replaceBits(cfg2, Config2_SA_HI, Config2_SA_LO, p->coreParams.CP0_Config2_SA); - replaceBits(cfg2, Config2_M, p->coreParams.CP0_Config2_M); + replaceBits(cfg2, Config2_TU_HI, Config2_TU_LO, cp.CP0_Config2_TU); + replaceBits(cfg2, Config2_TS_HI, Config2_TS_LO, cp.CP0_Config2_TS); + replaceBits(cfg2, Config2_TL_HI, Config2_TL_LO, cp.CP0_Config2_TL); + replaceBits(cfg2, Config2_TA_HI, Config2_TA_LO, cp.CP0_Config2_TA); + replaceBits(cfg2, Config2_SU_HI, Config2_SU_LO, cp.CP0_Config2_SU); + replaceBits(cfg2, Config2_SS_HI, Config2_SS_LO, cp.CP0_Config2_SS); + replaceBits(cfg2, Config2_SL_HI, Config2_SL_LO, cp.CP0_Config2_SL); + replaceBits(cfg2, Config2_SA_HI, Config2_SA_LO, cp.CP0_Config2_SA); + replaceBits(cfg2, Config2_M, cp.CP0_Config2_M); setRegNoEffect(Config2, cfg2); // Now, create Write Mask for Config register MiscReg cfg2_Mask = 0x7000F000; // Read Only Register @@ -248,14 +251,14 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads, // Config3 MiscReg cfg3 = readRegNoEffect(Config3); - replaceBits(cfg3, Config3_DSPP_HI, Config3_DSPP_LO, p->coreParams.CP0_Config3_DSPP); - replaceBits(cfg3, Config3_LPA_HI, Config3_LPA_LO, p->coreParams.CP0_Config3_LPA); - replaceBits(cfg3, Config3_VEIC_HI, Config3_VEIC_LO, p->coreParams.CP0_Config3_VEIC); - replaceBits(cfg3, Config3_VINT_HI, Config3_VINT_LO, p->coreParams.CP0_Config3_VInt); - replaceBits(cfg3, Config3_SP_HI, Config3_SP_LO, p->coreParams.CP0_Config3_SP); - replaceBits(cfg3, Config3_MT_HI, Config3_MT_LO, p->coreParams.CP0_Config3_MT); - replaceBits(cfg3, Config3_SM_HI, Config3_SM_LO, p->coreParams.CP0_Config3_SM); - replaceBits(cfg3, Config3_TL_HI, Config3_TL_LO, p->coreParams.CP0_Config3_TL); + replaceBits(cfg3, Config3_DSPP_HI, Config3_DSPP_LO, cp.CP0_Config3_DSPP); + replaceBits(cfg3, Config3_LPA_HI, Config3_LPA_LO, cp.CP0_Config3_LPA); + replaceBits(cfg3, Config3_VEIC_HI, Config3_VEIC_LO, cp.CP0_Config3_VEIC); + replaceBits(cfg3, Config3_VINT_HI, Config3_VINT_LO, cp.CP0_Config3_VInt); + replaceBits(cfg3, Config3_SP_HI, Config3_SP_LO, cp.CP0_Config3_SP); + replaceBits(cfg3, Config3_MT_HI, Config3_MT_LO, cp.CP0_Config3_MT); + replaceBits(cfg3, Config3_SM_HI, Config3_SM_LO, cp.CP0_Config3_SM); + replaceBits(cfg3, Config3_TL_HI, Config3_TL_LO, cp.CP0_Config3_TL); setRegNoEffect(Config3, cfg3); // Now, create Write Mask for Config register MiscReg cfg3_Mask = 0; // Read Only Register @@ -264,7 +267,7 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads, // EBase - CPUNum MiscReg EB = readRegNoEffect(EBase); - replaceBits(EB, EBase_CPUNum_HI, EBase_CPUNum_LO, p->coreParams.CP0_EBase_CPUNum); + replaceBits(EB, EBase_CPUNum_HI, EBase_CPUNum_LO, cp.CP0_EBase_CPUNum); replaceBits(EB, 31, 31, 1); setRegNoEffect(EBase, EB); // Now, create Write Mask for Config register @@ -275,7 +278,7 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads, // SRS Control - HSS (Highest Shadow Set) MiscReg SC = readRegNoEffect(SRSCtl); - replaceBits(SC, SRSCtl_HSS_HI,SRSCtl_HSS_LO,p->coreParams.CP0_SrsCtl_HSS); + replaceBits(SC, SRSCtl_HSS_HI,SRSCtl_HSS_LO,cp.CP0_SrsCtl_HSS); setRegNoEffect(SRSCtl, SC); // Now, create Write Mask for the SRS Ctl register MiscReg SC_Mask = 0x0000F3C0; @@ -284,8 +287,8 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads, // IntCtl - IPTI, IPPCI MiscReg IC = readRegNoEffect(IntCtl); - replaceBits(IC, IntCtl_IPTI_HI,IntCtl_IPTI_LO,p->coreParams.CP0_IntCtl_IPTI); - replaceBits(IC, IntCtl_IPPCI_HI,IntCtl_IPPCI_LO,p->coreParams.CP0_IntCtl_IPPCI); + replaceBits(IC, IntCtl_IPTI_HI,IntCtl_IPTI_LO,cp.CP0_IntCtl_IPTI); + replaceBits(IC, IntCtl_IPPCI_HI,IntCtl_IPPCI_LO,cp.CP0_IntCtl_IPPCI); setRegNoEffect(IntCtl, IC); // Now, create Write Mask for the IntCtl register MiscReg IC_Mask = 0x000003E0; @@ -294,7 +297,7 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads, // Watch Hi - M - FIXME (More than 1 Watch register) MiscReg WHi = readRegNoEffect(WatchHi0); - replaceBits(WHi, WatchHi_M, p->coreParams.CP0_WatchHi_M); + replaceBits(WHi, WatchHi_M, cp.CP0_WatchHi_M); setRegNoEffect(WatchHi0, WHi); // Now, create Write Mask for the IntCtl register MiscReg wh_Mask = 0x7FFF0FFF; @@ -303,8 +306,8 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads, // Perf Ctr - M - FIXME (More than 1 PerfCnt Pair) MiscReg PCtr = readRegNoEffect(PerfCnt0); - replaceBits(PCtr, PerfCntCtl_M, p->coreParams.CP0_PerfCtr_M); - replaceBits(PCtr, PerfCntCtl_W, p->coreParams.CP0_PerfCtr_W); + replaceBits(PCtr, PerfCntCtl_M, cp.CP0_PerfCtr_M); + replaceBits(PCtr, PerfCntCtl_W, cp.CP0_PerfCtr_W); setRegNoEffect(PerfCnt0, PCtr); // Now, create Write Mask for the IntCtl register MiscReg pc_Mask = 0x00007FF; @@ -322,7 +325,7 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads, // PageGrain MiscReg pagegrain = readRegNoEffect(PageGrain); - replaceBits(pagegrain,PageGrain_ESP,p->coreParams.CP0_Config3_SP); + replaceBits(pagegrain,PageGrain_ESP,cp.CP0_Config3_SP); setRegNoEffect(PageGrain, pagegrain); // Now, create Write Mask for the IntCtl register MiscReg pg_Mask = 0x10000000; -- cgit v1.2.3 From 1b1a7e33e730db51f67bc2f124347afaa7b0e0e9 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 11 Aug 2008 14:47:49 -0700 Subject: style --- src/arch/mips/regfile/misc_regfile.cc | 143 +++++++++++++++++++++------------- src/arch/mips/regfile/misc_regfile.hh | 6 +- src/arch/sparc/miscregfile.cc | 13 ++-- src/arch/sparc/ua2005.cc | 64 +++++++-------- 4 files changed, 133 insertions(+), 93 deletions(-) (limited to 'src/arch') diff --git a/src/arch/mips/regfile/misc_regfile.cc b/src/arch/mips/regfile/misc_regfile.cc index 407851007..b82a94103 100755 --- a/src/arch/mips/regfile/misc_regfile.cc +++ b/src/arch/mips/regfile/misc_regfile.cc @@ -45,39 +45,49 @@ using namespace std; std::string MiscRegFile::miscRegNames[NumMiscRegs] = -{"Index", "MVPControl", "MVPConf0", "MVPConf1", "", "", "", "", - "Random", "VPEControl", "VPEConf0", "VPEConf1", "YQMask", "VPESchedule", "VPEScheFBack", "VPEOpt", - "EntryLo0", "TCStatus", "TCBind", "TCRestart", "TCHalt", "TCContext", "TCSchedule", "TCScheFBack", - "EntryLo1", "", "", "", "", "", "", "", - "Context", "ContextConfig", "", "", "", "", "", "", - "PageMask", "PageGrain", "", "", "", "", "", "", - "Wired", "SRSConf0", "SRCConf1", "SRSConf2", "SRSConf3", "SRSConf4", "", "", - "HWREna", "", "", "", "", "", "", "", - "BadVAddr", "", "", "", "", "", "", "", - "Count", "", "", "", "", "", "", "", - "EntryHi", "", "", "", "", "", "", "", - "Compare", "", "", "", "", "", "", "", - "Status", "IntCtl", "SRSCtl", "SRSMap", "", "", "", "", - "Cause", "", "", "", "", "", "", "", - "EPC", "", "", "", "", "", "", "", - "PRId", "EBase", "", "", "", "", "", "", - "Config", "Config1", "Config2", "Config3", "", "", "", "", - "LLAddr", "", "", "", "", "", "", "", - "WatchLo0", "WatchLo1", "WatchLo2", "WatchLo3", "WatchLo4", "WatchLo5", "WatchLo6", "WatchLo7", - "WatchHi0", "WatchHi1", "WatchHi2", "WatchHi3", "WatchHi4", "WatchHi5", "WatchHi6", "WatchHi7", - "XCContext64", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", - "Debug", "TraceControl1", "TraceControl2", "UserTraceData", "TraceBPC", "", "", "", - "DEPC", "", "", "", "", "", "", "", - "PerfCnt0", "PerfCnt1", "PerfCnt2", "PerfCnt3", "PerfCnt4", "PerfCnt5", "PerfCnt6", "PerfCnt7", - "ErrCtl", "", "", "", "", "", "", "", - "CacheErr0", "CacheErr1", "CacheErr2", "CacheErr3", "", "", "", "", - "TagLo0", "DataLo1", "TagLo2", "DataLo3", "TagLo4", "DataLo5", "TagLo6", "DataLo7", - "TagHi0", "DataHi1", "TagHi2", "DataHi3", "TagHi4", "DataHi5", "TagHi6", "DataHi7", - "ErrorEPC", "", "", "", "", "", "", "", - "DESAVE", "", "", "", "", "", "", "", - "LLFlag" +{ + "Index", "MVPControl", "MVPConf0", "MVPConf1", "", "", "", "", + "Random", "VPEControl", "VPEConf0", "VPEConf1", + "YQMask", "VPESchedule", "VPEScheFBack", "VPEOpt", + "EntryLo0", "TCStatus", "TCBind", "TCRestart", + "TCHalt", "TCContext", "TCSchedule", "TCScheFBack", + "EntryLo1", "", "", "", "", "", "", "", + "Context", "ContextConfig", "", "", "", "", "", "", + "PageMask", "PageGrain", "", "", "", "", "", "", + "Wired", "SRSConf0", "SRCConf1", "SRSConf2", + "SRSConf3", "SRSConf4", "", "", + "HWREna", "", "", "", "", "", "", "", + "BadVAddr", "", "", "", "", "", "", "", + "Count", "", "", "", "", "", "", "", + "EntryHi", "", "", "", "", "", "", "", + "Compare", "", "", "", "", "", "", "", + "Status", "IntCtl", "SRSCtl", "SRSMap", "", "", "", "", + "Cause", "", "", "", "", "", "", "", + "EPC", "", "", "", "", "", "", "", + "PRId", "EBase", "", "", "", "", "", "", + "Config", "Config1", "Config2", "Config3", "", "", "", "", + "LLAddr", "", "", "", "", "", "", "", + "WatchLo0", "WatchLo1", "WatchLo2", "WatchLo3", + "WatchLo4", "WatchLo5", "WatchLo6", "WatchLo7", + "WatchHi0", "WatchHi1", "WatchHi2", "WatchHi3", + "WatchHi4", "WatchHi5", "WatchHi6", "WatchHi7", + "XCContext64", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "Debug", "TraceControl1", "TraceControl2", "UserTraceData", + "TraceBPC", "", "", "", + "DEPC", "", "", "", "", "", "", "", + "PerfCnt0", "PerfCnt1", "PerfCnt2", "PerfCnt3", + "PerfCnt4", "PerfCnt5", "PerfCnt6", "PerfCnt7", + "ErrCtl", "", "", "", "", "", "", "", + "CacheErr0", "CacheErr1", "CacheErr2", "CacheErr3", "", "", "", "", + "TagLo0", "DataLo1", "TagLo2", "DataLo3", + "TagLo4", "DataLo5", "TagLo6", "DataLo7", + "TagHi0", "DataHi1", "TagHi2", "DataHi3", + "TagHi4", "DataHi5", "TagHi6", "DataHi7", + "ErrorEPC", "", "", "", "", "", "", "", + "DESAVE", "", "", "", "", "", "", "", + "LLFlag" }; MiscRegFile::MiscRegFile() @@ -212,7 +222,8 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads, // Config1 MiscReg cfg1 = readRegNoEffect(Config1); - replaceBits(cfg1, Config1_MMUSize_HI, Config1_MMUSize_LO, cp.CP0_Config1_MMU); + replaceBits(cfg1, Config1_MMUSize_HI, Config1_MMUSize_LO, + cp.CP0_Config1_MMU); replaceBits(cfg1, Config1_IS_HI, Config1_IS_LO, cp.CP0_Config1_IS); replaceBits(cfg1, Config1_IL_HI, Config1_IL_LO, cp.CP0_Config1_IL); replaceBits(cfg1, Config1_IA_HI, Config1_IA_LO, cp.CP0_Config1_IA); @@ -334,12 +345,18 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads, // Status MiscReg stat = readRegNoEffect(Status); - // Only CU0 and IE are modified on a reset - everything else needs to be controlled - // on a per CPU model basis - // replaceBits(stat, Status_CU0_HI,Status_CU0_LO, 1); // Enable CP0 on reset + // Only CU0 and IE are modified on a reset - everything else needs + // to be controlled on a per CPU model basis + + // Enable CP0 on reset + // replaceBits(stat, Status_CU0_HI,Status_CU0_LO, 1); + + // Enable ERL bit on a reset + replaceBits(stat, Status_ERL_HI, Status_ERL_LO, 1); + + // Enable BEV bit on a reset + replaceBits(stat, Status_BEV_HI, Status_BEV_LO, 1); - replaceBits(stat, Status_ERL_HI, Status_ERL_LO, 1); // Enable ERL bit on a reset - replaceBits(stat, Status_BEV_HI, Status_BEV_LO, 1); // Enable BEV bit on a reset setRegNoEffect(Status, stat); // Now, create Write Mask for the Status register MiscReg stat_Mask = 0xFF78FF17; @@ -440,7 +457,8 @@ MiscRegFile::readRegNoEffect(int reg_idx, unsigned tid) unsigned reg_sel = (bankType[misc_reg] == perThreadContext) ? tid : getVPENum(tid); DPRINTF(MipsPRA, "Reading CP0 Register:%u Select:%u (%s) (%lx).\n", - misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg),miscRegFile[misc_reg][reg_sel]); + misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg), + miscRegFile[misc_reg][reg_sel]); return miscRegFile[misc_reg][reg_sel]; } @@ -454,8 +472,10 @@ MiscRegFile::readReg(int reg_idx, int misc_reg = reg_idx - Ctrl_Base_DepTag; unsigned reg_sel = (bankType[misc_reg] == perThreadContext) ? tid : getVPENum(tid); - DPRINTF(MipsPRA, "Reading CP0 Register:%u Select:%u (%s) with effect (%lx).\n", - misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg),miscRegFile[misc_reg][reg_sel]); + DPRINTF(MipsPRA, + "Reading CP0 Register:%u Select:%u (%s) with effect (%lx).\n", + misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg), + miscRegFile[misc_reg][reg_sel]); switch (misc_reg) @@ -471,7 +491,9 @@ MiscRegFile::setRegNoEffect(int reg_idx, const MiscReg &val, unsigned tid) int misc_reg = reg_idx - Ctrl_Base_DepTag; unsigned reg_sel = (bankType[misc_reg] == perThreadContext) ? tid : getVPENum(tid); - DPRINTF(MipsPRA, "[tid:%i]: Setting (direct set) CP0 Register:%u Select:%u (%s) to %#x.\n", + DPRINTF(MipsPRA, + "[tid:%i]: Setting (direct set) CP0 Register:%u " + "Select:%u (%s) to %#x.\n", tid, misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg), val); miscRegFile[misc_reg][reg_sel] = val; @@ -483,7 +505,9 @@ MiscRegFile::setRegMask(int reg_idx, const MiscReg &val, unsigned tid) int misc_reg = reg_idx - Ctrl_Base_DepTag; unsigned reg_sel = (bankType[misc_reg] == perThreadContext) ? tid : getVPENum(tid); - DPRINTF(MipsPRA,"[tid:%i]: Setting CP0 Register: %u Select: %u (%s) to %#x\n",tid, misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg), val); + DPRINTF(MipsPRA, + "[tid:%i]: Setting CP0 Register: %u Select: %u (%s) to %#x\n", + tid, misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg), val); miscRegFile_WriteMask[misc_reg][reg_sel] = val; } @@ -500,7 +524,9 @@ MiscRegFile::setReg(int reg_idx, const MiscReg &val, int reg_sel = (bankType[misc_reg] == perThreadContext) ? tid : getVPENum(tid); - DPRINTF(MipsPRA, "[tid:%i]: Setting CP0 Register:%u Select:%u (%s) to %#x, with effect.\n", + DPRINTF(MipsPRA, + "[tid:%i]: Setting CP0 Register:%u " + "Select:%u (%s) to %#x, with effect.\n", tid, misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg), val); MiscReg cp0_val = filterCP0Write(misc_reg, reg_sel, val); @@ -509,16 +535,28 @@ MiscRegFile::setReg(int reg_idx, const MiscReg &val, scheduleCP0Update(1); } -/** This method doesn't need to adjust the Control Register Offset since - it has already been done in the calling method (setRegWithEffect) */ -MiscReg MiscRegFile::filterCP0Write(int misc_reg, int reg_sel, const MiscReg &val) +/** + * This method doesn't need to adjust the Control Register Offset + * since it has already been done in the calling method + * (setRegWithEffect) +*/ +MiscReg +MiscRegFile::filterCP0Write(int misc_reg, int reg_sel, const MiscReg &val) { MiscReg retVal = val; - retVal &= miscRegFile_WriteMask[misc_reg][reg_sel]; // Mask off read-only regions + + // Mask off read-only regions + retVal &= miscRegFile_WriteMask[misc_reg][reg_sel]; MiscReg curVal = miscRegFile[misc_reg][reg_sel]; - curVal &= (~miscRegFile_WriteMask[misc_reg][reg_sel]); // Mask off current alue with inverse mask (clear writeable bits) + // Mask off current alue with inverse mask (clear writeable bits) + curVal &= (~miscRegFile_WriteMask[misc_reg][reg_sel]); retVal |= curVal; // Combine the two - DPRINTF(MipsPRA,"filterCP0Write: Mask: %lx, Inverse Mask: %lx, write Val: %x, current val: %lx, written val: %x\n",miscRegFile_WriteMask[misc_reg][reg_sel],~miscRegFile_WriteMask[misc_reg][reg_sel],val,miscRegFile[misc_reg][reg_sel],retVal); + DPRINTF(MipsPRA, + "filterCP0Write: Mask: %lx, Inverse Mask: %lx, write Val: %x, " + "current val: %lx, written val: %x\n", + miscRegFile_WriteMask[misc_reg][reg_sel], + ~miscRegFile_WriteMask[misc_reg][reg_sel], + val, miscRegFile[misc_reg][reg_sel], retVal); return retVal; } void @@ -563,7 +601,8 @@ MiscRegFile::updateCPU() } MiscRegFile::CP0Event::CP0Event(CP0 *_cp0, BaseCPU *_cpu, CP0EventType e_type) - : Event(&mainEventQueue, CPU_Tick_Pri), cp0(_cp0), cpu(_cpu), cp0EventType(e_type) + : Event(&mainEventQueue, CPU_Tick_Pri), cp0(_cp0), cpu(_cpu), + cp0EventType(e_type) { } void diff --git a/src/arch/mips/regfile/misc_regfile.hh b/src/arch/mips/regfile/misc_regfile.hh index 5f19579b3..4bec9a49e 100644 --- a/src/arch/mips/regfile/misc_regfile.hh +++ b/src/arch/mips/regfile/misc_regfile.hh @@ -75,7 +75,8 @@ namespace MipsISA void clear(unsigned tid_or_vpn = 0); - void reset(std::string core_name, unsigned num_threads, unsigned num_vpes, BaseCPU *_cpu); + void reset(std::string core_name, unsigned num_threads, + unsigned num_vpes, BaseCPU *_cpu); void expandForMultithreading(unsigned num_threads, unsigned num_vpes); @@ -98,7 +99,8 @@ namespace MipsISA MiscReg filterCP0Write(int misc_reg, int reg_sel, const MiscReg &val); void setRegMask(int misc_reg, const MiscReg &val, unsigned tid = 0); - void setRegNoEffect(int misc_reg, const MiscReg &val, unsigned tid = 0); + void setRegNoEffect(int misc_reg, const MiscReg &val, + unsigned tid = 0); //template void setReg(int misc_reg, const MiscReg &val, diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index 7b9c73433..195db90a6 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -322,12 +322,14 @@ MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc) return readFSReg(miscReg, tc); #else case MISCREG_HPSTATE: - //HPSTATE is special because because sometimes in privilege checks for instructions - //it will read HPSTATE to make sure the priv. level is ok - //So, we'll just have to tell it it isn't, instead of panicing. + //HPSTATE is special because because sometimes in privilege + //checks for instructions it will read HPSTATE to make sure + //the priv. level is ok So, we'll just have to tell it it + //isn't, instead of panicing. return 0; - panic("Accessing Fullsystem register %s in SE mode\n",getMiscRegName(miscReg)); + panic("Accessing Fullsystem register %s in SE mode\n", + getMiscRegName(miscReg)); #endif } @@ -584,7 +586,8 @@ void MiscRegFile::setReg(int miscReg, //HPSTATE is special because normal trap processing saves HPSTATE when //it goes into a trap, and restores it when it returns. return; - panic("Accessing Fullsystem register %s to %#x in SE mode\n", getMiscRegName(miscReg), val); + panic("Accessing Fullsystem register %s to %#x in SE mode\n", + getMiscRegName(miscReg), val); #endif } setRegNoEffect(miscReg, new_val); diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index fe733813c..990250159 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -40,22 +40,24 @@ using namespace SparcISA; void MiscRegFile::checkSoftInt(ThreadContext *tc) { + BaseCPU *cpu = tc->getCpuPtr(); + // If PIL < 14, copy over the tm and sm bits if (pil < 14 && softint & 0x10000) - tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,16); + cpu->post_interrupt(IT_SOFT_INT, 16); else - tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,16); + cpu->clear_interrupt(IT_SOFT_INT, 16); if (pil < 14 && softint & 0x1) - tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,0); + cpu->post_interrupt(IT_SOFT_INT, 0); else - tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,0); + cpu->clear_interrupt(IT_SOFT_INT, 0); // Copy over any of the other bits that are set for (int bit = 15; bit > 0; --bit) { if (1 << bit & softint && bit > pil) - tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,bit); + cpu->post_interrupt(IT_SOFT_INT, bit); else - tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,bit); + cpu->clear_interrupt(IT_SOFT_INT, bit); } } @@ -63,6 +65,8 @@ MiscRegFile::checkSoftInt(ThreadContext *tc) void MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) { + BaseCPU *cpu = tc->getCpuPtr(); + int64_t time; switch (miscReg) { /* Full system only ASRs */ @@ -85,7 +89,7 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) if (!(tick_cmpr & ~mask(63)) && time > 0) { if (tickCompare->scheduled()) tickCompare->deschedule(); - tickCompare->schedule(time * tc->getCpuPtr()->ticks(1)); + tickCompare->schedule(time * cpu->ticks(1)); } panic("writing to TICK compare register %#X\n", val); break; @@ -97,11 +101,11 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled()) sTickCompare->deschedule(); time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - - tc->getCpuPtr()->instCount(); + cpu->instCount(); if (!(stick_cmpr & ~mask(63)) && time > 0) { if (sTickCompare->scheduled()) sTickCompare->deschedule(); - sTickCompare->schedule(time * tc->getCpuPtr()->ticks(1) + curTick); + sTickCompare->schedule(time * cpu->ticks(1) + curTick); } DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val); break; @@ -120,9 +124,9 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) case MISCREG_HINTP: setRegNoEffect(miscReg, val); if (hintp) - tc->getCpuPtr()->post_interrupt(IT_HINTP,0); + cpu->post_interrupt(IT_HINTP, 0); else - tc->getCpuPtr()->clear_interrupt(IT_HINTP,0); + cpu->clear_interrupt(IT_HINTP, 0); break; case MISCREG_HTBA: @@ -134,25 +138,25 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) case MISCREG_QUEUE_CPU_MONDO_TAIL: setRegNoEffect(miscReg, val); if (cpu_mondo_head != cpu_mondo_tail) - tc->getCpuPtr()->post_interrupt(IT_CPU_MONDO,0); + cpu->post_interrupt(IT_CPU_MONDO, 0); else - tc->getCpuPtr()->clear_interrupt(IT_CPU_MONDO,0); + cpu->clear_interrupt(IT_CPU_MONDO, 0); break; case MISCREG_QUEUE_DEV_MONDO_HEAD: case MISCREG_QUEUE_DEV_MONDO_TAIL: setRegNoEffect(miscReg, val); if (dev_mondo_head != dev_mondo_tail) - tc->getCpuPtr()->post_interrupt(IT_DEV_MONDO,0); + cpu->post_interrupt(IT_DEV_MONDO, 0); else - tc->getCpuPtr()->clear_interrupt(IT_DEV_MONDO,0); + cpu->clear_interrupt(IT_DEV_MONDO, 0); break; case MISCREG_QUEUE_RES_ERROR_HEAD: case MISCREG_QUEUE_RES_ERROR_TAIL: setRegNoEffect(miscReg, val); if (res_error_head != res_error_tail) - tc->getCpuPtr()->post_interrupt(IT_RES_ERROR,0); + cpu->post_interrupt(IT_RES_ERROR, 0); else - tc->getCpuPtr()->clear_interrupt(IT_RES_ERROR,0); + cpu->clear_interrupt(IT_RES_ERROR, 0); break; case MISCREG_QUEUE_NRES_ERROR_HEAD: case MISCREG_QUEUE_NRES_ERROR_TAIL: @@ -167,11 +171,11 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled()) hSTickCompare->deschedule(); time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - - tc->getCpuPtr()->instCount(); + cpu->instCount(); if (!(hstick_cmpr & ~mask(63)) && time > 0) { if (hSTickCompare->scheduled()) hSTickCompare->deschedule(); - hSTickCompare->schedule(curTick + time * tc->getCpuPtr()->ticks(1)); + hSTickCompare->schedule(curTick + time * cpu->ticks(1)); } DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val); break; @@ -181,9 +185,9 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) setRegNoEffect(miscReg, val | HPSTATE::id); #if FULL_SYSTEM if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv)) - tc->getCpuPtr()->post_interrupt(IT_TRAP_LEVEL_ZERO,0); + cpu->post_interrupt(IT_TRAP_LEVEL_ZERO, 0); else - tc->getCpuPtr()->clear_interrupt(IT_TRAP_LEVEL_ZERO,0); + cpu->clear_interrupt(IT_TRAP_LEVEL_ZERO, 0); #endif break; case MISCREG_HTSTATE: @@ -200,11 +204,12 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) tc->suspend(); if (tc->getKernelStats()) tc->getKernelStats()->quiesce(); - } + } break; default: - panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg)); + panic("Invalid write to FS misc register %s\n", + getMiscRegName(miscReg)); } } @@ -250,7 +255,8 @@ MiscRegFile::readFSReg(int miscReg, ThreadContext * tc) sys = tc->getSystemPtr(); temp = readRegNoEffect(miscReg) & (STS::active | STS::speculative); - // Check that the CPU array is fully populated (by calling getNumCPus()) + // Check that the CPU array is fully populated + // (by calling getNumCPus()) assert(sys->getNumCPUs() > tc->readCpuId()); temp |= tc->readCpuId() << STS::shft_id; @@ -280,16 +286,6 @@ MiscRegFile::readFSReg(int miscReg, ThreadContext * tc) panic("Invalid read to FS misc register\n"); } } -/* - In Niagra STICK==TICK so this isn't needed - case MISCREG_STICK: - SparcSystem *sys; - sys = dynamic_cast(tc->getSystemPtr()); - assert(sys != NULL); - return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63))); -*/ - - void MiscRegFile::processTickCompare(ThreadContext *tc) -- cgit v1.2.3 From 91d968783ecbcbe4bcd44e10964532303b367a05 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Wed, 13 Aug 2008 16:29:59 -0400 Subject: Return an UnimpFault for an ITB translation of an uncachable address. We don't support fetching from uncached addresses in Alpha and it means that a speculative fetch can clobber device registers. --- src/arch/alpha/tlb.cc | 10 ++++++++-- src/arch/alpha/tlb.hh | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc index 77bf5e285..4f960360e 100644 --- a/src/arch/alpha/tlb.cc +++ b/src/arch/alpha/tlb.cc @@ -116,7 +116,7 @@ TLB::lookup(Addr vpn, uint8_t asn) Fault -TLB::checkCacheability(RequestPtr &req) +TLB::checkCacheability(RequestPtr &req, bool itb) { // in Alpha, cacheability is controlled by upper-level bits of the // physical address @@ -148,6 +148,12 @@ TLB::checkCacheability(RequestPtr &req) req->setPaddr(req->getPaddr() & PAddrUncachedMask); #endif } + // We shouldn't be able to read from an uncachable address in Alpha as + // we don't have a ROM and we don't want to try to fetch from a device + // register as we destroy any data that is clear-on-read. + if (req->isUncacheable() && itb) + return new UnimpFault("CPU trying to fetch from uncached I/O"); + } return NoFault; } @@ -390,7 +396,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) if (req->getPaddr() & ~PAddrImplMask) return genMachineCheckFault(); - return checkCacheability(req); + return checkCacheability(req, true); } diff --git a/src/arch/alpha/tlb.hh b/src/arch/alpha/tlb.hh index e61ae5c6d..f94d06ccd 100644 --- a/src/arch/alpha/tlb.hh +++ b/src/arch/alpha/tlb.hh @@ -92,7 +92,7 @@ namespace AlphaISA return (unimplBits == 0) || (unimplBits == EV5::VAddrUnImplMask); } - static Fault checkCacheability(RequestPtr &req); + static Fault checkCacheability(RequestPtr &req, bool itb = false); // Checkpointing virtual void serialize(std::ostream &os); -- cgit v1.2.3 From 30bc897613a1ee36ed887eb9da1579bd9828186e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 3 Sep 2008 00:52:54 -0400 Subject: X86: Fix the microcode for sign/zero extending moves that use high byte registers. --- src/arch/x86/isa/insts/general_purpose/data_transfer/move.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py index d9a83dfde..35f0436f5 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py @@ -126,7 +126,8 @@ def macroop MOVSXD_R_P { }; def macroop MOVSX_B_R_R { - sexti reg, regm, 7 + mov t1, t1, regm, dataSize=1 + sexti reg, t1, 7 }; def macroop MOVSX_B_R_M { @@ -160,7 +161,8 @@ def macroop MOVSX_W_R_P { # def macroop MOVZX_B_R_R { - zexti reg, regm, 7 + mov t1, t1, regm, dataSize=1 + zexti reg, t1, 7 }; def macroop MOVZX_B_R_M { -- cgit v1.2.3 From 09a8fb0b5263d4b41b8206ce075a3f6923907d65 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 9 Sep 2008 16:27:17 -0700 Subject: style: this file did not conform to style --- src/arch/mips/regfile/int_regfile.cc | 44 ++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 24 deletions(-) (limited to 'src/arch') diff --git a/src/arch/mips/regfile/int_regfile.cc b/src/arch/mips/regfile/int_regfile.cc index c46ecf0b3..4ffbcdfb8 100644 --- a/src/arch/mips/regfile/int_regfile.cc +++ b/src/arch/mips/regfile/int_regfile.cc @@ -37,7 +37,6 @@ using namespace MipsISA; using namespace std; - void IntRegFile::clear() { @@ -48,25 +47,27 @@ IntRegFile::clear() void IntRegFile::setShadowSet(int css) { - DPRINTF(MipsPRA,"Setting Shadow Set to :%d (%s)\n",css,currShadowSet); + DPRINTF(MipsPRA, "Setting Shadow Set to :%d (%s)\n", css, currShadowSet); currShadowSet = css; } IntReg IntRegFile::readReg(int intReg) { - if(intReg < NumIntRegs) - { // Regular GPR Read - DPRINTF(MipsPRA,"Reading Reg: %d, CurrShadowSet: %d\n",intReg,currShadowSet); - if(intReg >= NumIntArchRegs*NumShadowRegSets){ - return regs[intReg+NumIntRegs*currShadowSet]; - } - else { - return regs[(intReg + NumIntArchRegs*currShadowSet) % NumIntArchRegs]; + if (intReg < NumIntRegs) { + // Regular GPR Read + DPRINTF(MipsPRA, "Reading Reg: %d, CurrShadowSet: %d\n", intReg, + currShadowSet); + + if (intReg >= NumIntArchRegs * NumShadowRegSets) { + return regs[intReg + NumIntRegs * currShadowSet]; + } else { + int index = intReg + NumIntArchRegs * currShadowSet; + index = index % NumIntArchRegs; + return regs[index]; } - } - else - { // Read from shadow GPR .. probably called by RDPGPR + } else { + // Read from shadow GPR .. probably called by RDPGPR return regs[intReg]; } } @@ -75,20 +76,16 @@ Fault IntRegFile::setReg(int intReg, const IntReg &val) { if (intReg != ZeroReg) { - - if(intReg < NumIntRegs) - { - if(intReg >= NumIntArchRegs*NumShadowRegSets){ + if (intReg < NumIntRegs) { + if (intReg >= NumIntArchRegs * NumShadowRegSets) regs[intReg] = val; - } - else{ - regs[intReg+NumIntRegs*currShadowSet] = val; - } - } - else{ + else + regs[intReg + NumIntRegs * currShadowSet] = val; + } else { regs[intReg] = val; } } + return NoFault; } @@ -103,4 +100,3 @@ IntRegFile::unserialize(Checkpoint *cp, const std::string §ion) { UNSERIALIZE_ARRAY(regs, NumIntRegs); } - -- cgit v1.2.3 From 3a3e356f4e61e86f6f1427dd85cf1e41fa9125c0 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Wed, 10 Sep 2008 14:26:15 -0400 Subject: style: Remove non-leading tabs everywhere they shouldn't be. Developers should configure their editors to not insert tabs --- src/arch/alpha/aout_machdep.h | 42 +- src/arch/alpha/ev5.cc | 2 +- src/arch/alpha/floatregfile.hh | 4 +- src/arch/alpha/ipr.cc | 144 +++--- src/arch/alpha/ipr.hh | 152 +++--- src/arch/alpha/isa_traits.hh | 14 +- src/arch/alpha/linux/linux.cc | 40 +- src/arch/alpha/linux/linux.hh | 30 +- src/arch/alpha/miscregfile.hh | 10 +- src/arch/alpha/osfpal.cc | 512 ++++++++++----------- src/arch/alpha/pagetable.hh | 18 +- src/arch/alpha/regfile.hh | 12 +- src/arch/alpha/remote_gdb.cc | 26 +- src/arch/alpha/system.cc | 6 +- src/arch/alpha/tlb.cc | 2 +- src/arch/alpha/tru64/process.cc | 10 +- src/arch/alpha/tru64/tru64.cc | 40 +- src/arch/alpha/tru64/tru64.hh | 40 +- src/arch/isa_parser.py | 10 +- src/arch/isa_specific.hh | 2 +- src/arch/mips/isa_traits.hh | 10 +- src/arch/mips/linux/linux.cc | 40 +- src/arch/mips/linux/linux.hh | 40 +- src/arch/mips/regfile/regfile.hh | 12 +- src/arch/mips/system.cc | 6 +- src/arch/mips/tlb.cc | 32 +- src/arch/mips/tlb.hh | 8 +- src/arch/sparc/isa_traits.hh | 2 +- src/arch/sparc/linux/linux.cc | 40 +- src/arch/sparc/linux/linux.hh | 30 +- src/arch/sparc/miscregfile.hh | 56 +-- src/arch/sparc/regfile.hh | 10 +- src/arch/sparc/remote_gdb.cc | 26 +- src/arch/sparc/solaris/solaris.cc | 52 +-- src/arch/sparc/solaris/solaris.hh | 20 +- src/arch/sparc/sparc_traits.hh | 4 +- .../general_purpose/cache_and_memory_management.py | 14 +- .../insts/general_purpose/control_transfer/call.py | 2 +- .../control_transfer/interrupts_and_exceptions.py | 4 +- .../data_conversion/ascii_adjust.py | 8 +- .../general_purpose/data_conversion/bcd_adjust.py | 4 +- .../data_conversion/endian_conversion.py | 2 +- .../data_conversion/extract_sign_mask.py | 4 +- .../insts/general_purpose/data_transfer/move.py | 4 +- .../general_purpose/load_segment_registers.py | 14 +- .../x86/isa/insts/general_purpose/semaphores.py | 4 +- .../x86/isa/insts/general_purpose/system_calls.py | 8 +- src/arch/x86/linux/linux.hh | 30 +- src/arch/x86/remote_gdb.cc | 16 +- 49 files changed, 809 insertions(+), 809 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/aout_machdep.h b/src/arch/alpha/aout_machdep.h index 58991256a..bcf004d05 100644 --- a/src/arch/alpha/aout_machdep.h +++ b/src/arch/alpha/aout_machdep.h @@ -36,35 +36,35 @@ /// Funky Alpha 64-bit a.out header used for PAL code. /// struct aout_exechdr { - uint16_t magic; ///< magic number - uint16_t vstamp; ///< version stamp? - uint16_t bldrev; ///< ??? - uint16_t padcell; ///< padding - uint64_t tsize; ///< text segment size - uint64_t dsize; ///< data segment size - uint64_t bsize; ///< bss segment size - uint64_t entry; ///< entry point - uint64_t text_start; ///< text base address - uint64_t data_start; ///< data base address - uint64_t bss_start; ///< bss base address - uint32_t gprmask; ///< GPR mask (unused, AFAIK) - uint32_t fprmask; ///< FPR mask (unused, AFAIK) - uint64_t gp_value; ///< global pointer reg value + uint16_t magic; ///< magic number + uint16_t vstamp; ///< version stamp? + uint16_t bldrev; ///< ??? + uint16_t padcell; ///< padding + uint64_t tsize; ///< text segment size + uint64_t dsize; ///< data segment size + uint64_t bsize; ///< bss segment size + uint64_t entry; ///< entry point + uint64_t text_start; ///< text base address + uint64_t data_start; ///< data base address + uint64_t bss_start; ///< bss base address + uint32_t gprmask; ///< GPR mask (unused, AFAIK) + uint32_t fprmask; ///< FPR mask (unused, AFAIK) + uint64_t gp_value; ///< global pointer reg value }; -#define AOUT_LDPGSZ 8192 +#define AOUT_LDPGSZ 8192 -#define N_GETMAGIC(ex) ((ex).magic) +#define N_GETMAGIC(ex) ((ex).magic) #define N_BADMAX -#define N_TXTADDR(ex) ((ex).text_start) -#define N_DATADDR(ex) ((ex).data_start) -#define N_BSSADDR(ex) ((ex).bss_start) +#define N_TXTADDR(ex) ((ex).text_start) +#define N_DATADDR(ex) ((ex).data_start) +#define N_BSSADDR(ex) ((ex).bss_start) -#define N_TXTOFF(ex) \ +#define N_TXTOFF(ex) \ (N_GETMAGIC(ex) == ZMAGIC ? 0 : sizeof(struct aout_exechdr)) -#define N_DATOFF(ex) N_ALIGN(ex, N_TXTOFF(ex) + (ex).tsize) +#define N_DATOFF(ex) N_ALIGN(ex, N_TXTOFF(ex) + (ex).tsize) #endif /* !__AOUT_MACHDEP_H__*/ diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index 5dc49623e..33306d6af 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -176,7 +176,7 @@ AlphaISA::initIPRs(ThreadContext *tc, int cpuId) AlphaISA::MiscReg AlphaISA::MiscRegFile::readIpr(int idx, ThreadContext *tc) { - uint64_t retval = 0; // return value, default 0 + uint64_t retval = 0; // return value, default 0 switch (idx) { case AlphaISA::IPR_PALtemp0: diff --git a/src/arch/alpha/floatregfile.hh b/src/arch/alpha/floatregfile.hh index 0c5fe17a7..e69e8d186 100644 --- a/src/arch/alpha/floatregfile.hh +++ b/src/arch/alpha/floatregfile.hh @@ -52,8 +52,8 @@ namespace AlphaISA public: union { - uint64_t q[NumFloatRegs]; // integer qword view - double d[NumFloatRegs]; // double-precision floating point view + uint64_t q[NumFloatRegs]; // integer qword view + double d[NumFloatRegs]; // double-precision floating point view }; void serialize(std::ostream &os); diff --git a/src/arch/alpha/ipr.cc b/src/arch/alpha/ipr.cc index 8e83102eb..a76fcc2bc 100644 --- a/src/arch/alpha/ipr.cc +++ b/src/arch/alpha/ipr.cc @@ -38,89 +38,89 @@ namespace AlphaISA md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs] = { //Write only - RAW_IPR_HWINT_CLR, // H/W interrupt clear register - RAW_IPR_SL_XMIT, // serial line transmit register + RAW_IPR_HWINT_CLR, // H/W interrupt clear register + RAW_IPR_SL_XMIT, // serial line transmit register RAW_IPR_DC_FLUSH, - RAW_IPR_IC_FLUSH, // instruction cache flush control - RAW_IPR_ALT_MODE, // alternate mode register - RAW_IPR_DTB_IA, // DTLB invalidate all register - RAW_IPR_DTB_IAP, // DTLB invalidate all process register - RAW_IPR_ITB_IA, // ITLB invalidate all register - RAW_IPR_ITB_IAP, // ITLB invalidate all process register + RAW_IPR_IC_FLUSH, // instruction cache flush control + RAW_IPR_ALT_MODE, // alternate mode register + RAW_IPR_DTB_IA, // DTLB invalidate all register + RAW_IPR_DTB_IAP, // DTLB invalidate all process register + RAW_IPR_ITB_IA, // ITLB invalidate all register + RAW_IPR_ITB_IAP, // ITLB invalidate all process register //Read only - RAW_IPR_INTID, // interrupt ID register - RAW_IPR_SL_RCV, // serial line receive register - RAW_IPR_MM_STAT, // data MMU fault status register - RAW_IPR_ITB_PTE_TEMP, // ITLB page table entry temp register - RAW_IPR_DTB_PTE_TEMP, // DTLB page table entry temporary register + RAW_IPR_INTID, // interrupt ID register + RAW_IPR_SL_RCV, // serial line receive register + RAW_IPR_MM_STAT, // data MMU fault status register + RAW_IPR_ITB_PTE_TEMP, // ITLB page table entry temp register + RAW_IPR_DTB_PTE_TEMP, // DTLB page table entry temporary register - RAW_IPR_ISR, // interrupt summary register - RAW_IPR_ITB_TAG, // ITLB tag register - RAW_IPR_ITB_PTE, // ITLB page table entry register - RAW_IPR_ITB_ASN, // ITLB address space register - RAW_IPR_ITB_IS, // ITLB invalidate select register - RAW_IPR_SIRR, // software interrupt request register - RAW_IPR_ASTRR, // asynchronous system trap request register - RAW_IPR_ASTER, // asynchronous system trap enable register - RAW_IPR_EXC_ADDR, // exception address register - RAW_IPR_EXC_SUM, // exception summary register - RAW_IPR_EXC_MASK, // exception mask register - RAW_IPR_PAL_BASE, // PAL base address register - RAW_IPR_ICM, // instruction current mode - RAW_IPR_IPLR, // interrupt priority level register - RAW_IPR_IFAULT_VA_FORM, // formatted faulting virtual addr register - RAW_IPR_IVPTBR, // virtual page table base register - RAW_IPR_ICSR, // instruction control and status register - RAW_IPR_IC_PERR_STAT, // inst cache parity error status register - RAW_IPR_PMCTR, // performance counter register + RAW_IPR_ISR, // interrupt summary register + RAW_IPR_ITB_TAG, // ITLB tag register + RAW_IPR_ITB_PTE, // ITLB page table entry register + RAW_IPR_ITB_ASN, // ITLB address space register + RAW_IPR_ITB_IS, // ITLB invalidate select register + RAW_IPR_SIRR, // software interrupt request register + RAW_IPR_ASTRR, // asynchronous system trap request register + RAW_IPR_ASTER, // asynchronous system trap enable register + RAW_IPR_EXC_ADDR, // exception address register + RAW_IPR_EXC_SUM, // exception summary register + RAW_IPR_EXC_MASK, // exception mask register + RAW_IPR_PAL_BASE, // PAL base address register + RAW_IPR_ICM, // instruction current mode + RAW_IPR_IPLR, // interrupt priority level register + RAW_IPR_IFAULT_VA_FORM, // formatted faulting virtual addr register + RAW_IPR_IVPTBR, // virtual page table base register + RAW_IPR_ICSR, // instruction control and status register + RAW_IPR_IC_PERR_STAT, // inst cache parity error status register + RAW_IPR_PMCTR, // performance counter register // PAL temporary registers... // register meanings gleaned from osfpal.s source code - RAW_IPR_PALtemp0, // local scratch - RAW_IPR_PALtemp1, // local scratch - RAW_IPR_PALtemp2, // entUna - RAW_IPR_PALtemp3, // CPU specific impure area pointer - RAW_IPR_PALtemp4, // memory management temp - RAW_IPR_PALtemp5, // memory management temp - RAW_IPR_PALtemp6, // memory management temp - RAW_IPR_PALtemp7, // entIF - RAW_IPR_PALtemp8, // intmask - RAW_IPR_PALtemp9, // entSys - RAW_IPR_PALtemp10, // ?? - RAW_IPR_PALtemp11, // entInt - RAW_IPR_PALtemp12, // entArith - RAW_IPR_PALtemp13, // reserved for platform specific PAL - RAW_IPR_PALtemp14, // reserved for platform specific PAL - RAW_IPR_PALtemp15, // reserved for platform specific PAL - RAW_IPR_PALtemp16, // scratch / whami<7:0> / mces<4:0> - RAW_IPR_PALtemp17, // sysval - RAW_IPR_PALtemp18, // usp - RAW_IPR_PALtemp19, // ksp - RAW_IPR_PALtemp20, // PTBR - RAW_IPR_PALtemp21, // entMM - RAW_IPR_PALtemp22, // kgp - RAW_IPR_PALtemp23, // PCBB + RAW_IPR_PALtemp0, // local scratch + RAW_IPR_PALtemp1, // local scratch + RAW_IPR_PALtemp2, // entUna + RAW_IPR_PALtemp3, // CPU specific impure area pointer + RAW_IPR_PALtemp4, // memory management temp + RAW_IPR_PALtemp5, // memory management temp + RAW_IPR_PALtemp6, // memory management temp + RAW_IPR_PALtemp7, // entIF + RAW_IPR_PALtemp8, // intmask + RAW_IPR_PALtemp9, // entSys + RAW_IPR_PALtemp10, // ?? + RAW_IPR_PALtemp11, // entInt + RAW_IPR_PALtemp12, // entArith + RAW_IPR_PALtemp13, // reserved for platform specific PAL + RAW_IPR_PALtemp14, // reserved for platform specific PAL + RAW_IPR_PALtemp15, // reserved for platform specific PAL + RAW_IPR_PALtemp16, // scratch / whami<7:0> / mces<4:0> + RAW_IPR_PALtemp17, // sysval + RAW_IPR_PALtemp18, // usp + RAW_IPR_PALtemp19, // ksp + RAW_IPR_PALtemp20, // PTBR + RAW_IPR_PALtemp21, // entMM + RAW_IPR_PALtemp22, // kgp + RAW_IPR_PALtemp23, // PCBB - RAW_IPR_DTB_ASN, // DTLB address space number register - RAW_IPR_DTB_CM, // DTLB current mode register - RAW_IPR_DTB_TAG, // DTLB tag register - RAW_IPR_DTB_PTE, // DTLB page table entry register + RAW_IPR_DTB_ASN, // DTLB address space number register + RAW_IPR_DTB_CM, // DTLB current mode register + RAW_IPR_DTB_TAG, // DTLB tag register + RAW_IPR_DTB_PTE, // DTLB page table entry register - RAW_IPR_VA, // fault virtual address register - RAW_IPR_VA_FORM, // formatted virtual address register - RAW_IPR_MVPTBR, // MTU virtual page table base register - RAW_IPR_DTB_IS, // DTLB invalidate single register - RAW_IPR_CC, // cycle counter register - RAW_IPR_CC_CTL, // cycle counter control register - RAW_IPR_MCSR, // MTU control register + RAW_IPR_VA, // fault virtual address register + RAW_IPR_VA_FORM, // formatted virtual address register + RAW_IPR_MVPTBR, // MTU virtual page table base register + RAW_IPR_DTB_IS, // DTLB invalidate single register + RAW_IPR_CC, // cycle counter register + RAW_IPR_CC_CTL, // cycle counter control register + RAW_IPR_MCSR, // MTU control register - RAW_IPR_DC_PERR_STAT, // Dcache parity error status register - RAW_IPR_DC_TEST_CTL, // Dcache test tag control register - RAW_IPR_DC_TEST_TAG, // Dcache test tag register + RAW_IPR_DC_PERR_STAT, // Dcache parity error status register + RAW_IPR_DC_TEST_CTL, // Dcache test tag control register + RAW_IPR_DC_TEST_TAG, // Dcache test tag register RAW_IPR_DC_TEST_TAG_TEMP, // Dcache test tag temporary register - RAW_IPR_DC_MODE, // Dcache mode register - RAW_IPR_MAF_MODE // miss address file mode register + RAW_IPR_DC_MODE, // Dcache mode register + RAW_IPR_MAF_MODE // miss address file mode register }; int IprToMiscRegIndex[MaxInternalProcRegs]; diff --git a/src/arch/alpha/ipr.hh b/src/arch/alpha/ipr.hh index b55154764..6296cdb9a 100644 --- a/src/arch/alpha/ipr.hh +++ b/src/arch/alpha/ipr.hh @@ -40,88 +40,88 @@ namespace AlphaISA // enum md_ipr_names { - RAW_IPR_ISR = 0x100, // interrupt summary register - RAW_IPR_ITB_TAG = 0x101, // ITLB tag register - RAW_IPR_ITB_PTE = 0x102, // ITLB page table entry register - RAW_IPR_ITB_ASN = 0x103, // ITLB address space register - RAW_IPR_ITB_PTE_TEMP = 0x104, // ITLB page table entry temp register - RAW_IPR_ITB_IA = 0x105, // ITLB invalidate all register - RAW_IPR_ITB_IAP = 0x106, // ITLB invalidate all process register - RAW_IPR_ITB_IS = 0x107, // ITLB invalidate select register - RAW_IPR_SIRR = 0x108, // software interrupt request register - RAW_IPR_ASTRR = 0x109, // asynchronous system trap request register - RAW_IPR_ASTER = 0x10a, // asynchronous system trap enable register - RAW_IPR_EXC_ADDR = 0x10b, // exception address register - RAW_IPR_EXC_SUM = 0x10c, // exception summary register - RAW_IPR_EXC_MASK = 0x10d, // exception mask register - RAW_IPR_PAL_BASE = 0x10e, // PAL base address register - RAW_IPR_ICM = 0x10f, // instruction current mode - RAW_IPR_IPLR = 0x110, // interrupt priority level register - RAW_IPR_INTID = 0x111, // interrupt ID register - RAW_IPR_IFAULT_VA_FORM = 0x112, // formatted faulting virtual addr register - RAW_IPR_IVPTBR = 0x113, // virtual page table base register - RAW_IPR_HWINT_CLR = 0x115, // H/W interrupt clear register - RAW_IPR_SL_XMIT = 0x116, // serial line transmit register - RAW_IPR_SL_RCV = 0x117, // serial line receive register - RAW_IPR_ICSR = 0x118, // instruction control and status register - RAW_IPR_IC_FLUSH = 0x119, // instruction cache flush control - RAW_IPR_IC_PERR_STAT = 0x11a, // inst cache parity error status register - RAW_IPR_PMCTR = 0x11c, // performance counter register + RAW_IPR_ISR = 0x100, // interrupt summary register + RAW_IPR_ITB_TAG = 0x101, // ITLB tag register + RAW_IPR_ITB_PTE = 0x102, // ITLB page table entry register + RAW_IPR_ITB_ASN = 0x103, // ITLB address space register + RAW_IPR_ITB_PTE_TEMP = 0x104, // ITLB page table entry temp register + RAW_IPR_ITB_IA = 0x105, // ITLB invalidate all register + RAW_IPR_ITB_IAP = 0x106, // ITLB invalidate all process register + RAW_IPR_ITB_IS = 0x107, // ITLB invalidate select register + RAW_IPR_SIRR = 0x108, // software interrupt request register + RAW_IPR_ASTRR = 0x109, // asynchronous system trap request register + RAW_IPR_ASTER = 0x10a, // asynchronous system trap enable register + RAW_IPR_EXC_ADDR = 0x10b, // exception address register + RAW_IPR_EXC_SUM = 0x10c, // exception summary register + RAW_IPR_EXC_MASK = 0x10d, // exception mask register + RAW_IPR_PAL_BASE = 0x10e, // PAL base address register + RAW_IPR_ICM = 0x10f, // instruction current mode + RAW_IPR_IPLR = 0x110, // interrupt priority level register + RAW_IPR_INTID = 0x111, // interrupt ID register + RAW_IPR_IFAULT_VA_FORM = 0x112, // formatted faulting virtual addr register + RAW_IPR_IVPTBR = 0x113, // virtual page table base register + RAW_IPR_HWINT_CLR = 0x115, // H/W interrupt clear register + RAW_IPR_SL_XMIT = 0x116, // serial line transmit register + RAW_IPR_SL_RCV = 0x117, // serial line receive register + RAW_IPR_ICSR = 0x118, // instruction control and status register + RAW_IPR_IC_FLUSH = 0x119, // instruction cache flush control + RAW_IPR_IC_PERR_STAT = 0x11a, // inst cache parity error status register + RAW_IPR_PMCTR = 0x11c, // performance counter register // PAL temporary registers... // register meanings gleaned from osfpal.s source code - RAW_IPR_PALtemp0 = 0x140, // local scratch - RAW_IPR_PALtemp1 = 0x141, // local scratch - RAW_IPR_PALtemp2 = 0x142, // entUna - RAW_IPR_PALtemp3 = 0x143, // CPU specific impure area pointer - RAW_IPR_PALtemp4 = 0x144, // memory management temp - RAW_IPR_PALtemp5 = 0x145, // memory management temp - RAW_IPR_PALtemp6 = 0x146, // memory management temp - RAW_IPR_PALtemp7 = 0x147, // entIF - RAW_IPR_PALtemp8 = 0x148, // intmask - RAW_IPR_PALtemp9 = 0x149, // entSys - RAW_IPR_PALtemp10 = 0x14a, // ?? - RAW_IPR_PALtemp11 = 0x14b, // entInt - RAW_IPR_PALtemp12 = 0x14c, // entArith - RAW_IPR_PALtemp13 = 0x14d, // reserved for platform specific PAL - RAW_IPR_PALtemp14 = 0x14e, // reserved for platform specific PAL - RAW_IPR_PALtemp15 = 0x14f, // reserved for platform specific PAL - RAW_IPR_PALtemp16 = 0x150, // scratch / whami<7:0> / mces<4:0> - RAW_IPR_PALtemp17 = 0x151, // sysval - RAW_IPR_PALtemp18 = 0x152, // usp - RAW_IPR_PALtemp19 = 0x153, // ksp - RAW_IPR_PALtemp20 = 0x154, // PTBR - RAW_IPR_PALtemp21 = 0x155, // entMM - RAW_IPR_PALtemp22 = 0x156, // kgp - RAW_IPR_PALtemp23 = 0x157, // PCBB - - RAW_IPR_DTB_ASN = 0x200, // DTLB address space number register - RAW_IPR_DTB_CM = 0x201, // DTLB current mode register - RAW_IPR_DTB_TAG = 0x202, // DTLB tag register - RAW_IPR_DTB_PTE = 0x203, // DTLB page table entry register - RAW_IPR_DTB_PTE_TEMP = 0x204, // DTLB page table entry temporary register - - RAW_IPR_MM_STAT = 0x205, // data MMU fault status register - RAW_IPR_VA = 0x206, // fault virtual address register - RAW_IPR_VA_FORM = 0x207, // formatted virtual address register - RAW_IPR_MVPTBR = 0x208, // MTU virtual page table base register - RAW_IPR_DTB_IAP = 0x209, // DTLB invalidate all process register - RAW_IPR_DTB_IA = 0x20a, // DTLB invalidate all register - RAW_IPR_DTB_IS = 0x20b, // DTLB invalidate single register - RAW_IPR_ALT_MODE = 0x20c, // alternate mode register - RAW_IPR_CC = 0x20d, // cycle counter register - RAW_IPR_CC_CTL = 0x20e, // cycle counter control register - RAW_IPR_MCSR = 0x20f, // MTU control register + RAW_IPR_PALtemp0 = 0x140, // local scratch + RAW_IPR_PALtemp1 = 0x141, // local scratch + RAW_IPR_PALtemp2 = 0x142, // entUna + RAW_IPR_PALtemp3 = 0x143, // CPU specific impure area pointer + RAW_IPR_PALtemp4 = 0x144, // memory management temp + RAW_IPR_PALtemp5 = 0x145, // memory management temp + RAW_IPR_PALtemp6 = 0x146, // memory management temp + RAW_IPR_PALtemp7 = 0x147, // entIF + RAW_IPR_PALtemp8 = 0x148, // intmask + RAW_IPR_PALtemp9 = 0x149, // entSys + RAW_IPR_PALtemp10 = 0x14a, // ?? + RAW_IPR_PALtemp11 = 0x14b, // entInt + RAW_IPR_PALtemp12 = 0x14c, // entArith + RAW_IPR_PALtemp13 = 0x14d, // reserved for platform specific PAL + RAW_IPR_PALtemp14 = 0x14e, // reserved for platform specific PAL + RAW_IPR_PALtemp15 = 0x14f, // reserved for platform specific PAL + RAW_IPR_PALtemp16 = 0x150, // scratch / whami<7:0> / mces<4:0> + RAW_IPR_PALtemp17 = 0x151, // sysval + RAW_IPR_PALtemp18 = 0x152, // usp + RAW_IPR_PALtemp19 = 0x153, // ksp + RAW_IPR_PALtemp20 = 0x154, // PTBR + RAW_IPR_PALtemp21 = 0x155, // entMM + RAW_IPR_PALtemp22 = 0x156, // kgp + RAW_IPR_PALtemp23 = 0x157, // PCBB + + RAW_IPR_DTB_ASN = 0x200, // DTLB address space number register + RAW_IPR_DTB_CM = 0x201, // DTLB current mode register + RAW_IPR_DTB_TAG = 0x202, // DTLB tag register + RAW_IPR_DTB_PTE = 0x203, // DTLB page table entry register + RAW_IPR_DTB_PTE_TEMP = 0x204, // DTLB page table entry temporary register + + RAW_IPR_MM_STAT = 0x205, // data MMU fault status register + RAW_IPR_VA = 0x206, // fault virtual address register + RAW_IPR_VA_FORM = 0x207, // formatted virtual address register + RAW_IPR_MVPTBR = 0x208, // MTU virtual page table base register + RAW_IPR_DTB_IAP = 0x209, // DTLB invalidate all process register + RAW_IPR_DTB_IA = 0x20a, // DTLB invalidate all register + RAW_IPR_DTB_IS = 0x20b, // DTLB invalidate single register + RAW_IPR_ALT_MODE = 0x20c, // alternate mode register + RAW_IPR_CC = 0x20d, // cycle counter register + RAW_IPR_CC_CTL = 0x20e, // cycle counter control register + RAW_IPR_MCSR = 0x20f, // MTU control register RAW_IPR_DC_FLUSH = 0x210, - RAW_IPR_DC_PERR_STAT = 0x212, // Dcache parity error status register - RAW_IPR_DC_TEST_CTL = 0x213, // Dcache test tag control register - RAW_IPR_DC_TEST_TAG = 0x214, // Dcache test tag register + RAW_IPR_DC_PERR_STAT = 0x212, // Dcache parity error status register + RAW_IPR_DC_TEST_CTL = 0x213, // Dcache test tag control register + RAW_IPR_DC_TEST_TAG = 0x214, // Dcache test tag register RAW_IPR_DC_TEST_TAG_TEMP = 0x215, // Dcache test tag temporary register - RAW_IPR_DC_MODE = 0x216, // Dcache mode register - RAW_IPR_MAF_MODE = 0x217, // miss address file mode register + RAW_IPR_DC_MODE = 0x216, // Dcache mode register + RAW_IPR_MAF_MODE = 0x217, // miss address file mode register - MaxInternalProcRegs // number of IPR registers + MaxInternalProcRegs // number of IPR registers }; enum MiscRegIpr @@ -215,7 +215,7 @@ namespace AlphaISA IPR_DC_MODE, IPR_MAF_MODE, - NumInternalProcRegs // number of IPR registers + NumInternalProcRegs // number of IPR registers }; inline bool IprIsWritable(int index) diff --git a/src/arch/alpha/isa_traits.hh b/src/arch/alpha/isa_traits.hh index be1d1b8bb..4837d4a34 100644 --- a/src/arch/alpha/isa_traits.hh +++ b/src/arch/alpha/isa_traits.hh @@ -123,11 +123,11 @@ namespace AlphaISA // EV5 modes enum mode_type { - mode_kernel = 0, // kernel - mode_executive = 1, // executive (unused by unix) - mode_supervisor = 2, // supervisor (unused by unix) - mode_user = 3, // user mode - mode_number // number of modes + mode_kernel = 0, // kernel + mode_executive = 1, // executive (unused by unix) + mode_supervisor = 2, // supervisor (unused by unix) + mode_user = 3, // user mode + mode_number // number of modes }; // Constants Related to the number of registers @@ -148,7 +148,7 @@ namespace AlphaISA const int TotalDataRegs = NumIntRegs + NumFloatRegs; // semantically meaningful register indices - const int ZeroReg = 31; // architecturally meaningful + const int ZeroReg = 31; // architecturally meaningful // the rest of these depend on the ABI const int StackPointerReg = 30; const int GlobalPointerReg = 29; @@ -164,7 +164,7 @@ namespace AlphaISA const int SyscallPseudoReturnReg = ArgumentReg[4]; const int SyscallSuccessReg = 19; - const int LogVMPageSize = 13; // 8K bytes + const int LogVMPageSize = 13; // 8K bytes const int VMPageSize = (1 << LogVMPageSize); const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned diff --git a/src/arch/alpha/linux/linux.cc b/src/arch/alpha/linux/linux.cc index e6908a572..3e80f62a7 100644 --- a/src/arch/alpha/linux/linux.cc +++ b/src/arch/alpha/linux/linux.cc @@ -35,34 +35,34 @@ // open(2) flags translation table OpenFlagTransTable AlphaLinux::openFlagTable[] = { #ifdef _MSC_VER - { AlphaLinux::TGT_O_RDONLY, _O_RDONLY }, - { AlphaLinux::TGT_O_WRONLY, _O_WRONLY }, - { AlphaLinux::TGT_O_RDWR, _O_RDWR }, - { AlphaLinux::TGT_O_APPEND, _O_APPEND }, - { AlphaLinux::TGT_O_CREAT, _O_CREAT }, - { AlphaLinux::TGT_O_TRUNC, _O_TRUNC }, - { AlphaLinux::TGT_O_EXCL, _O_EXCL }, + { AlphaLinux::TGT_O_RDONLY, _O_RDONLY }, + { AlphaLinux::TGT_O_WRONLY, _O_WRONLY }, + { AlphaLinux::TGT_O_RDWR, _O_RDWR }, + { AlphaLinux::TGT_O_APPEND, _O_APPEND }, + { AlphaLinux::TGT_O_CREAT, _O_CREAT }, + { AlphaLinux::TGT_O_TRUNC, _O_TRUNC }, + { AlphaLinux::TGT_O_EXCL, _O_EXCL }, #ifdef _O_NONBLOCK - { AlphaLinux::TGT_O_NONBLOCK, _O_NONBLOCK }, + { AlphaLinux::TGT_O_NONBLOCK, _O_NONBLOCK }, #endif #ifdef _O_NOCTTY - { AlphaLinux::TGT_O_NOCTTY, _O_NOCTTY }, + { AlphaLinux::TGT_O_NOCTTY, _O_NOCTTY }, #endif #ifdef _O_SYNC - { AlphaLinux::TGT_O_SYNC, _O_SYNC }, + { AlphaLinux::TGT_O_SYNC, _O_SYNC }, #endif #else /* !_MSC_VER */ - { AlphaLinux::TGT_O_RDONLY, O_RDONLY }, - { AlphaLinux::TGT_O_WRONLY, O_WRONLY }, - { AlphaLinux::TGT_O_RDWR, O_RDWR }, - { AlphaLinux::TGT_O_APPEND, O_APPEND }, - { AlphaLinux::TGT_O_CREAT, O_CREAT }, - { AlphaLinux::TGT_O_TRUNC, O_TRUNC }, - { AlphaLinux::TGT_O_EXCL, O_EXCL }, - { AlphaLinux::TGT_O_NONBLOCK, O_NONBLOCK }, - { AlphaLinux::TGT_O_NOCTTY, O_NOCTTY }, + { AlphaLinux::TGT_O_RDONLY, O_RDONLY }, + { AlphaLinux::TGT_O_WRONLY, O_WRONLY }, + { AlphaLinux::TGT_O_RDWR, O_RDWR }, + { AlphaLinux::TGT_O_APPEND, O_APPEND }, + { AlphaLinux::TGT_O_CREAT, O_CREAT }, + { AlphaLinux::TGT_O_TRUNC, O_TRUNC }, + { AlphaLinux::TGT_O_EXCL, O_EXCL }, + { AlphaLinux::TGT_O_NONBLOCK, O_NONBLOCK }, + { AlphaLinux::TGT_O_NOCTTY, O_NOCTTY }, #ifdef O_SYNC - { AlphaLinux::TGT_O_SYNC, O_SYNC }, + { AlphaLinux::TGT_O_SYNC, O_SYNC }, #endif #endif /* _MSC_VER */ }; diff --git a/src/arch/alpha/linux/linux.hh b/src/arch/alpha/linux/linux.hh index 84c04ebc3..803970aa9 100644 --- a/src/arch/alpha/linux/linux.hh +++ b/src/arch/alpha/linux/linux.hh @@ -50,21 +50,21 @@ class AlphaLinux : public Linux //@{ /// open(2) flag values. - static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY - static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY - static const int TGT_O_RDWR = 00000002; //!< O_RDWR - static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK - static const int TGT_O_APPEND = 00000010; //!< O_APPEND - static const int TGT_O_CREAT = 00001000; //!< O_CREAT - static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC - static const int TGT_O_EXCL = 00004000; //!< O_EXCL - static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY - static const int TGT_O_SYNC = 00040000; //!< O_SYNC - static const int TGT_O_DRD = 00100000; //!< O_DRD - static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO - static const int TGT_O_CACHE = 00400000; //!< O_CACHE - static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC - static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC + static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY + static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY + static const int TGT_O_RDWR = 00000002; //!< O_RDWR + static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK + static const int TGT_O_APPEND = 00000010; //!< O_APPEND + static const int TGT_O_CREAT = 00001000; //!< O_CREAT + static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC + static const int TGT_O_EXCL = 00004000; //!< O_EXCL + static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY + static const int TGT_O_SYNC = 00040000; //!< O_SYNC + static const int TGT_O_DRD = 00100000; //!< O_DRD + static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO + static const int TGT_O_CACHE = 00400000; //!< O_CACHE + static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC + static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC //@} /// For mmap(). diff --git a/src/arch/alpha/miscregfile.hh b/src/arch/alpha/miscregfile.hh index 022b6404a..f07b998e6 100644 --- a/src/arch/alpha/miscregfile.hh +++ b/src/arch/alpha/miscregfile.hh @@ -60,11 +60,11 @@ namespace AlphaISA class MiscRegFile { protected: - uint64_t fpcr; // floating point condition codes - uint64_t uniq; // process-unique register - bool lock_flag; // lock flag for LL/SC - Addr lock_addr; // lock address for LL/SC - int intr_flag; + uint64_t fpcr; // floating point condition codes + uint64_t uniq; // process-unique register + bool lock_flag; // lock flag for LL/SC + Addr lock_addr; // lock address for LL/SC + int intr_flag; public: MiscRegFile() diff --git a/src/arch/alpha/osfpal.cc b/src/arch/alpha/osfpal.cc index ed1d255a6..0edbadb06 100644 --- a/src/arch/alpha/osfpal.cc +++ b/src/arch/alpha/osfpal.cc @@ -33,265 +33,265 @@ namespace { const char *strings[PAL::NumCodes] = { // Priviledged PAL instructions - "halt", // 0x00 - "cflush", // 0x01 - "draina", // 0x02 - 0, // 0x03 - 0, // 0x04 - 0, // 0x05 - 0, // 0x06 - 0, // 0x07 - 0, // 0x08 - "cserve", // 0x09 - "swppal", // 0x0a - 0, // 0x0b - 0, // 0x0c - "wripir", // 0x0d - 0, // 0x0e - 0, // 0x0f - "rdmces", // 0x10 - "wrmces", // 0x11 - 0, // 0x12 - 0, // 0x13 - 0, // 0x14 - 0, // 0x15 - 0, // 0x16 - 0, // 0x17 - 0, // 0x18 - 0, // 0x19 - 0, // 0x1a - 0, // 0x1b - 0, // 0x1c - 0, // 0x1d - 0, // 0x1e - 0, // 0x1f - 0, // 0x20 - 0, // 0x21 - 0, // 0x22 - 0, // 0x23 - 0, // 0x24 - 0, // 0x25 - 0, // 0x26 - 0, // 0x27 - 0, // 0x28 - 0, // 0x29 - 0, // 0x2a - "wrfen", // 0x2b - 0, // 0x2c - "wrvptptr", // 0x2d - 0, // 0x2e - 0, // 0x2f - "swpctx", // 0x30 - "wrval", // 0x31 - "rdval", // 0x32 - "tbi", // 0x33 - "wrent", // 0x34 - "swpipl", // 0x35 - "rdps", // 0x36 - "wrkgp", // 0x37 - "wrusp", // 0x38 - "wrperfmon", // 0x39 - "rdusp", // 0x3a - 0, // 0x3b - "whami", // 0x3c - "retsys", // 0x3d - "wtint", // 0x3e - "rti", // 0x3f - 0, // 0x40 - 0, // 0x41 - 0, // 0x42 - 0, // 0x43 - 0, // 0x44 - 0, // 0x45 - 0, // 0x46 - 0, // 0x47 - 0, // 0x48 - 0, // 0x49 - 0, // 0x4a - 0, // 0x4b - 0, // 0x4c - 0, // 0x4d - 0, // 0x4e - 0, // 0x4f - 0, // 0x50 - 0, // 0x51 - 0, // 0x52 - 0, // 0x53 - 0, // 0x54 - 0, // 0x55 - 0, // 0x56 - 0, // 0x57 - 0, // 0x58 - 0, // 0x59 - 0, // 0x5a - 0, // 0x5b - 0, // 0x5c - 0, // 0x5d - 0, // 0x5e - 0, // 0x5f - 0, // 0x60 - 0, // 0x61 - 0, // 0x62 - 0, // 0x63 - 0, // 0x64 - 0, // 0x65 - 0, // 0x66 - 0, // 0x67 - 0, // 0x68 - 0, // 0x69 - 0, // 0x6a - 0, // 0x6b - 0, // 0x6c - 0, // 0x6d - 0, // 0x6e - 0, // 0x6f - 0, // 0x70 - 0, // 0x71 - 0, // 0x72 - 0, // 0x73 - 0, // 0x74 - 0, // 0x75 - 0, // 0x76 - 0, // 0x77 - 0, // 0x78 - 0, // 0x79 - 0, // 0x7a - 0, // 0x7b - 0, // 0x7c - 0, // 0x7d - 0, // 0x7e - 0, // 0x7f + "halt", // 0x00 + "cflush", // 0x01 + "draina", // 0x02 + 0, // 0x03 + 0, // 0x04 + 0, // 0x05 + 0, // 0x06 + 0, // 0x07 + 0, // 0x08 + "cserve", // 0x09 + "swppal", // 0x0a + 0, // 0x0b + 0, // 0x0c + "wripir", // 0x0d + 0, // 0x0e + 0, // 0x0f + "rdmces", // 0x10 + "wrmces", // 0x11 + 0, // 0x12 + 0, // 0x13 + 0, // 0x14 + 0, // 0x15 + 0, // 0x16 + 0, // 0x17 + 0, // 0x18 + 0, // 0x19 + 0, // 0x1a + 0, // 0x1b + 0, // 0x1c + 0, // 0x1d + 0, // 0x1e + 0, // 0x1f + 0, // 0x20 + 0, // 0x21 + 0, // 0x22 + 0, // 0x23 + 0, // 0x24 + 0, // 0x25 + 0, // 0x26 + 0, // 0x27 + 0, // 0x28 + 0, // 0x29 + 0, // 0x2a + "wrfen", // 0x2b + 0, // 0x2c + "wrvptptr", // 0x2d + 0, // 0x2e + 0, // 0x2f + "swpctx", // 0x30 + "wrval", // 0x31 + "rdval", // 0x32 + "tbi", // 0x33 + "wrent", // 0x34 + "swpipl", // 0x35 + "rdps", // 0x36 + "wrkgp", // 0x37 + "wrusp", // 0x38 + "wrperfmon", // 0x39 + "rdusp", // 0x3a + 0, // 0x3b + "whami", // 0x3c + "retsys", // 0x3d + "wtint", // 0x3e + "rti", // 0x3f + 0, // 0x40 + 0, // 0x41 + 0, // 0x42 + 0, // 0x43 + 0, // 0x44 + 0, // 0x45 + 0, // 0x46 + 0, // 0x47 + 0, // 0x48 + 0, // 0x49 + 0, // 0x4a + 0, // 0x4b + 0, // 0x4c + 0, // 0x4d + 0, // 0x4e + 0, // 0x4f + 0, // 0x50 + 0, // 0x51 + 0, // 0x52 + 0, // 0x53 + 0, // 0x54 + 0, // 0x55 + 0, // 0x56 + 0, // 0x57 + 0, // 0x58 + 0, // 0x59 + 0, // 0x5a + 0, // 0x5b + 0, // 0x5c + 0, // 0x5d + 0, // 0x5e + 0, // 0x5f + 0, // 0x60 + 0, // 0x61 + 0, // 0x62 + 0, // 0x63 + 0, // 0x64 + 0, // 0x65 + 0, // 0x66 + 0, // 0x67 + 0, // 0x68 + 0, // 0x69 + 0, // 0x6a + 0, // 0x6b + 0, // 0x6c + 0, // 0x6d + 0, // 0x6e + 0, // 0x6f + 0, // 0x70 + 0, // 0x71 + 0, // 0x72 + 0, // 0x73 + 0, // 0x74 + 0, // 0x75 + 0, // 0x76 + 0, // 0x77 + 0, // 0x78 + 0, // 0x79 + 0, // 0x7a + 0, // 0x7b + 0, // 0x7c + 0, // 0x7d + 0, // 0x7e + 0, // 0x7f // Unpriviledged PAL instructions - "bpt", // 0x80 - "bugchk", // 0x81 - 0, // 0x82 - "callsys", // 0x83 - 0, // 0x84 - 0, // 0x85 - "imb", // 0x86 - 0, // 0x87 - 0, // 0x88 - 0, // 0x89 - 0, // 0x8a - 0, // 0x8b - 0, // 0x8c - 0, // 0x8d - 0, // 0x8e - 0, // 0x8f - 0, // 0x90 - 0, // 0x91 - "urti", // 0x92 - 0, // 0x93 - 0, // 0x94 - 0, // 0x95 - 0, // 0x96 - 0, // 0x97 - 0, // 0x98 - 0, // 0x99 - 0, // 0x9a - 0, // 0x9b - 0, // 0x9c - 0, // 0x9d - "rdunique", // 0x9e - "wrunique", // 0x9f - 0, // 0xa0 - 0, // 0xa1 - 0, // 0xa2 - 0, // 0xa3 - 0, // 0xa4 - 0, // 0xa5 - 0, // 0xa6 - 0, // 0xa7 - 0, // 0xa8 - 0, // 0xa9 - "gentrap", // 0xaa - 0, // 0xab - 0, // 0xac - 0, // 0xad - "clrfen", // 0xae - 0, // 0xaf - 0, // 0xb0 - 0, // 0xb1 - 0, // 0xb2 - 0, // 0xb3 - 0, // 0xb4 - 0, // 0xb5 - 0, // 0xb6 - 0, // 0xb7 - 0, // 0xb8 - 0, // 0xb9 - 0, // 0xba - 0, // 0xbb - 0, // 0xbc - 0, // 0xbd - "nphalt", // 0xbe - "copypal", // 0xbf + "bpt", // 0x80 + "bugchk", // 0x81 + 0, // 0x82 + "callsys", // 0x83 + 0, // 0x84 + 0, // 0x85 + "imb", // 0x86 + 0, // 0x87 + 0, // 0x88 + 0, // 0x89 + 0, // 0x8a + 0, // 0x8b + 0, // 0x8c + 0, // 0x8d + 0, // 0x8e + 0, // 0x8f + 0, // 0x90 + 0, // 0x91 + "urti", // 0x92 + 0, // 0x93 + 0, // 0x94 + 0, // 0x95 + 0, // 0x96 + 0, // 0x97 + 0, // 0x98 + 0, // 0x99 + 0, // 0x9a + 0, // 0x9b + 0, // 0x9c + 0, // 0x9d + "rdunique", // 0x9e + "wrunique", // 0x9f + 0, // 0xa0 + 0, // 0xa1 + 0, // 0xa2 + 0, // 0xa3 + 0, // 0xa4 + 0, // 0xa5 + 0, // 0xa6 + 0, // 0xa7 + 0, // 0xa8 + 0, // 0xa9 + "gentrap", // 0xaa + 0, // 0xab + 0, // 0xac + 0, // 0xad + "clrfen", // 0xae + 0, // 0xaf + 0, // 0xb0 + 0, // 0xb1 + 0, // 0xb2 + 0, // 0xb3 + 0, // 0xb4 + 0, // 0xb5 + 0, // 0xb6 + 0, // 0xb7 + 0, // 0xb8 + 0, // 0xb9 + 0, // 0xba + 0, // 0xbb + 0, // 0xbc + 0, // 0xbd + "nphalt", // 0xbe + "copypal", // 0xbf #if 0 - 0, // 0xc0 - 0, // 0xc1 - 0, // 0xc2 - 0, // 0xc3 - 0, // 0xc4 - 0, // 0xc5 - 0, // 0xc6 - 0, // 0xc7 - 0, // 0xc8 - 0, // 0xc9 - 0, // 0xca - 0, // 0xcb - 0, // 0xcc - 0, // 0xcd - 0, // 0xce - 0, // 0xcf - 0, // 0xd0 - 0, // 0xd1 - 0, // 0xd2 - 0, // 0xd3 - 0, // 0xd4 - 0, // 0xd5 - 0, // 0xd6 - 0, // 0xd7 - 0, // 0xd8 - 0, // 0xd9 - 0, // 0xda - 0, // 0xdb - 0, // 0xdc - 0, // 0xdd - 0, // 0xde - 0, // 0xdf - 0, // 0xe0 - 0, // 0xe1 - 0, // 0xe2 - 0, // 0xe3 - 0, // 0xe4 - 0, // 0xe5 - 0, // 0xe6 - 0, // 0xe7 - 0, // 0xe8 - 0, // 0xe9 - 0, // 0xea - 0, // 0xeb - 0, // 0xec - 0, // 0xed - 0, // 0xee - 0, // 0xef - 0, // 0xf0 - 0, // 0xf1 - 0, // 0xf2 - 0, // 0xf3 - 0, // 0xf4 - 0, // 0xf5 - 0, // 0xf6 - 0, // 0xf7 - 0, // 0xf8 - 0, // 0xf9 - 0, // 0xfa - 0, // 0xfb - 0, // 0xfc - 0, // 0xfd - 0, // 0xfe - 0 // 0xff + 0, // 0xc0 + 0, // 0xc1 + 0, // 0xc2 + 0, // 0xc3 + 0, // 0xc4 + 0, // 0xc5 + 0, // 0xc6 + 0, // 0xc7 + 0, // 0xc8 + 0, // 0xc9 + 0, // 0xca + 0, // 0xcb + 0, // 0xcc + 0, // 0xcd + 0, // 0xce + 0, // 0xcf + 0, // 0xd0 + 0, // 0xd1 + 0, // 0xd2 + 0, // 0xd3 + 0, // 0xd4 + 0, // 0xd5 + 0, // 0xd6 + 0, // 0xd7 + 0, // 0xd8 + 0, // 0xd9 + 0, // 0xda + 0, // 0xdb + 0, // 0xdc + 0, // 0xdd + 0, // 0xde + 0, // 0xdf + 0, // 0xe0 + 0, // 0xe1 + 0, // 0xe2 + 0, // 0xe3 + 0, // 0xe4 + 0, // 0xe5 + 0, // 0xe6 + 0, // 0xe7 + 0, // 0xe8 + 0, // 0xe9 + 0, // 0xea + 0, // 0xeb + 0, // 0xec + 0, // 0xed + 0, // 0xee + 0, // 0xef + 0, // 0xf0 + 0, // 0xf1 + 0, // 0xf2 + 0, // 0xf3 + 0, // 0xf4 + 0, // 0xf5 + 0, // 0xf6 + 0, // 0xf7 + 0, // 0xf8 + 0, // 0xf9 + 0, // 0xfa + 0, // 0xfb + 0, // 0xfc + 0, // 0xfd + 0, // 0xfe + 0 // 0xff #endif }; } diff --git a/src/arch/alpha/pagetable.hh b/src/arch/alpha/pagetable.hh index 8ce5b4e5d..f28c1b195 100644 --- a/src/arch/alpha/pagetable.hh +++ b/src/arch/alpha/pagetable.hh @@ -110,15 +110,15 @@ namespace AlphaISA { TlbEntry() {} - Addr tag; // virtual page number tag - Addr ppn; // physical page number - uint8_t xre; // read permissions - VMEM_PERM_* mask - uint8_t xwe; // write permissions - VMEM_PERM_* mask - uint8_t asn; // address space number - bool asma; // address space match - bool fonr; // fault on read - bool fonw; // fault on write - bool valid; // valid page table entry + Addr tag; // virtual page number tag + Addr ppn; // physical page number + uint8_t xre; // read permissions - VMEM_PERM_* mask + uint8_t xwe; // write permissions - VMEM_PERM_* mask + uint8_t asn; // address space number + bool asma; // address space match + bool fonr; // fault on read + bool fonw; // fault on write + bool valid; // valid page table entry Addr pageStart() { diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh index 792a518fb..0c1f07bdd 100644 --- a/src/arch/alpha/regfile.hh +++ b/src/arch/alpha/regfile.hh @@ -51,8 +51,8 @@ namespace AlphaISA class RegFile { protected: - Addr pc; // program counter - Addr npc; // next-cycle program counter + Addr pc; // program counter + Addr npc; // next-cycle program counter Addr nnpc; public: @@ -85,14 +85,14 @@ namespace AlphaISA { } protected: - IntRegFile intRegFile; // (signed) integer register file - FloatRegFile floatRegFile; // floating point register file - MiscRegFile miscRegFile; // control register file + IntRegFile intRegFile; // (signed) integer register file + FloatRegFile floatRegFile; // floating point register file + MiscRegFile miscRegFile; // control register file public: #if FULL_SYSTEM - int intrflag; // interrupt flag + int intrflag; // interrupt flag inline int instAsid() { return miscRegFile.getInstAsid(); } inline int dataAsid() diff --git a/src/arch/alpha/remote_gdb.cc b/src/arch/alpha/remote_gdb.cc index ea5db36f4..8d70ebfa2 100644 --- a/src/arch/alpha/remote_gdb.cc +++ b/src/arch/alpha/remote_gdb.cc @@ -30,7 +30,7 @@ /* * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. + * The Regents of the University of California. All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and @@ -38,8 +38,8 @@ * * All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Lawrence Berkeley Laboratories. + * This product includes software developed by the University of + * California, Lawrence Berkeley Laboratories. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -51,8 +51,8 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. + * This product includes software developed by the University of + * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -69,7 +69,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94 + * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94 */ /*- @@ -89,8 +89,8 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. * 4. Neither the name of The NetBSD Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. @@ -151,7 +151,7 @@ RemoteGDB::RemoteGDB(System *_system, ThreadContext *c) /////////////////////////////////////////////////////////// // RemoteGDB::acc // -// Determine if the mapping at va..(va+len) is valid. +// Determine if the mapping at va..(va+len) is valid. // bool RemoteGDB::acc(Addr va, size_t len) @@ -204,8 +204,8 @@ RemoteGDB::acc(Addr va, size_t len) /////////////////////////////////////////////////////////// // RemoteGDB::getregs // -// Translate the kernel debugger register format into -// the GDB register format. +// Translate the kernel debugger register format into +// the GDB register format. void RemoteGDB::getregs() { @@ -234,8 +234,8 @@ RemoteGDB::getregs() /////////////////////////////////////////////////////////// // RemoteGDB::setregs // -// Translate the GDB register format into the kernel -// debugger register format. +// Translate the GDB register format into the kernel +// debugger register format. // void RemoteGDB::setregs() diff --git a/src/arch/alpha/system.cc b/src/arch/alpha/system.cc index 2af62ceea..f8fea4fee 100644 --- a/src/arch/alpha/system.cc +++ b/src/arch/alpha/system.cc @@ -142,9 +142,9 @@ AlphaSystem::~AlphaSystem() * in the procedure value register (pv aka t12 == r27). This sequence * looks like the following: * - * opcode Ra Rb offset - * ldah gp,X(pv) 09 29 27 X - * lda gp,Y(gp) 08 29 29 Y + * opcode Ra Rb offset + * ldah gp,X(pv) 09 29 27 X + * lda gp,Y(gp) 08 29 29 Y * * for some constant offsets X and Y. The catch is that the linker * (or maybe even the compiler, I'm not sure) may recognize that the diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc index 4f960360e..60502ebdb 100644 --- a/src/arch/alpha/tlb.cc +++ b/src/arch/alpha/tlb.cc @@ -55,7 +55,7 @@ bool uncacheBit39 = false; bool uncacheBit40 = false; #endif -#define MODE2MASK(X) (1 << (X)) +#define MODE2MASK(X) (1 << (X)) TLB::TLB(const Params *p) : BaseTLB(p), size(p->size), nlu(0) diff --git a/src/arch/alpha/tru64/process.cc b/src/arch/alpha/tru64/process.cc index e9f7b6be1..5f448489e 100644 --- a/src/arch/alpha/tru64/process.cc +++ b/src/arch/alpha/tru64/process.cc @@ -85,7 +85,7 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, case AlphaTru64::GSI_PHYSMEM: { TypedBufferArg physmem(tc->getSyscallArg(1)); - *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB + *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB physmem.copyOut(tc->getMemPort()); return 1; } @@ -168,11 +168,11 @@ SyscallReturn tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process, using namespace std; using namespace TheISA; - int id = tc->getSyscallArg(0); // table ID - int index = tc->getSyscallArg(1); // index into table + int id = tc->getSyscallArg(0); // table ID + int index = tc->getSyscallArg(1); // index into table // arg 2 is buffer pointer; type depends on table ID - int nel = tc->getSyscallArg(3); // number of elements - int lel = tc->getSyscallArg(4); // expected element size + int nel = tc->getSyscallArg(3); // number of elements + int lel = tc->getSyscallArg(4); // expected element size switch (id) { case AlphaTru64::TBL_SYSINFO: { diff --git a/src/arch/alpha/tru64/tru64.cc b/src/arch/alpha/tru64/tru64.cc index 56b04846f..c72e975f0 100644 --- a/src/arch/alpha/tru64/tru64.cc +++ b/src/arch/alpha/tru64/tru64.cc @@ -33,34 +33,34 @@ // open(2) flags translation table OpenFlagTransTable AlphaTru64::openFlagTable[] = { #ifdef _MSC_VER - { AlphaTru64::TGT_O_RDONLY, _O_RDONLY }, - { AlphaTru64::TGT_O_WRONLY, _O_WRONLY }, - { AlphaTru64::TGT_O_RDWR, _O_RDWR }, - { AlphaTru64::TGT_O_APPEND, _O_APPEND }, - { AlphaTru64::TGT_O_CREAT, _O_CREAT }, - { AlphaTru64::TGT_O_TRUNC, _O_TRUNC }, - { AlphaTru64::TGT_O_EXCL, _O_EXCL }, + { AlphaTru64::TGT_O_RDONLY, _O_RDONLY }, + { AlphaTru64::TGT_O_WRONLY, _O_WRONLY }, + { AlphaTru64::TGT_O_RDWR, _O_RDWR }, + { AlphaTru64::TGT_O_APPEND, _O_APPEND }, + { AlphaTru64::TGT_O_CREAT, _O_CREAT }, + { AlphaTru64::TGT_O_TRUNC, _O_TRUNC }, + { AlphaTru64::TGT_O_EXCL, _O_EXCL }, #ifdef _O_NONBLOCK - { AlphaTru64::TGT_O_NONBLOCK, _O_NONBLOCK }, + { AlphaTru64::TGT_O_NONBLOCK, _O_NONBLOCK }, #endif #ifdef _O_NOCTTY - { AlphaTru64::TGT_O_NOCTTY, _O_NOCTTY }, + { AlphaTru64::TGT_O_NOCTTY, _O_NOCTTY }, #endif #ifdef _O_SYNC - { AlphaTru64::TGT_O_SYNC, _O_SYNC }, + { AlphaTru64::TGT_O_SYNC, _O_SYNC }, #endif #else /* !_MSC_VER */ - { AlphaTru64::TGT_O_RDONLY, O_RDONLY }, - { AlphaTru64::TGT_O_WRONLY, O_WRONLY }, - { AlphaTru64::TGT_O_RDWR, O_RDWR }, - { AlphaTru64::TGT_O_APPEND, O_APPEND }, - { AlphaTru64::TGT_O_CREAT, O_CREAT }, - { AlphaTru64::TGT_O_TRUNC, O_TRUNC }, - { AlphaTru64::TGT_O_EXCL, O_EXCL }, - { AlphaTru64::TGT_O_NONBLOCK, O_NONBLOCK }, - { AlphaTru64::TGT_O_NOCTTY, O_NOCTTY }, + { AlphaTru64::TGT_O_RDONLY, O_RDONLY }, + { AlphaTru64::TGT_O_WRONLY, O_WRONLY }, + { AlphaTru64::TGT_O_RDWR, O_RDWR }, + { AlphaTru64::TGT_O_APPEND, O_APPEND }, + { AlphaTru64::TGT_O_CREAT, O_CREAT }, + { AlphaTru64::TGT_O_TRUNC, O_TRUNC }, + { AlphaTru64::TGT_O_EXCL, O_EXCL }, + { AlphaTru64::TGT_O_NONBLOCK, O_NONBLOCK }, + { AlphaTru64::TGT_O_NOCTTY, O_NOCTTY }, #ifdef O_SYNC - { AlphaTru64::TGT_O_SYNC, O_SYNC }, + { AlphaTru64::TGT_O_SYNC, O_SYNC }, #endif #endif /* _MSC_VER */ }; diff --git a/src/arch/alpha/tru64/tru64.hh b/src/arch/alpha/tru64/tru64.hh index 90e5f12dc..8aa959553 100644 --- a/src/arch/alpha/tru64/tru64.hh +++ b/src/arch/alpha/tru64/tru64.hh @@ -46,21 +46,21 @@ class AlphaTru64 : public Tru64 //@{ /// open(2) flag values. - static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY - static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY - static const int TGT_O_RDWR = 00000002; //!< O_RDWR - static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK - static const int TGT_O_APPEND = 00000010; //!< O_APPEND - static const int TGT_O_CREAT = 00001000; //!< O_CREAT - static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC - static const int TGT_O_EXCL = 00004000; //!< O_EXCL - static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY - static const int TGT_O_SYNC = 00040000; //!< O_SYNC - static const int TGT_O_DRD = 00100000; //!< O_DRD - static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO - static const int TGT_O_CACHE = 00400000; //!< O_CACHE - static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC - static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC + static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY + static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY + static const int TGT_O_RDWR = 00000002; //!< O_RDWR + static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK + static const int TGT_O_APPEND = 00000010; //!< O_APPEND + static const int TGT_O_CREAT = 00001000; //!< O_CREAT + static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC + static const int TGT_O_EXCL = 00004000; //!< O_EXCL + static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY + static const int TGT_O_SYNC = 00040000; //!< O_SYNC + static const int TGT_O_DRD = 00100000; //!< O_DRD + static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO + static const int TGT_O_CACHE = 00400000; //!< O_CACHE + static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC + static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC //@} /// For mmap(). @@ -69,12 +69,12 @@ class AlphaTru64 : public Tru64 //@{ /// For getsysinfo(). static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string - static const unsigned GSI_CPU_INFO = 59; //!< CPU information - static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type + static const unsigned GSI_CPU_INFO = 59; //!< CPU information + static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine - static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system - static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB - static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz + static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system + static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB + static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz //@} //@{ diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index bbdd95bb0..25cf84b30 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -116,7 +116,7 @@ t_SEMI = r';' t_DOT = r'\.' t_COLON = r':' t_DBLCOLON = r'::' -t_ASTERISK = r'\*' +t_ASTERISK = r'\*' # Identifiers and reserved words reserved_map = { } @@ -480,7 +480,7 @@ def p_excess_args_param(t): # # A decode block looks like: -# decode [, ]* [default ] { ... } +# decode [, ]* [default ] { ... } # def p_decode_block(t): 'decode_block : DECODE ID opt_default LBRACE decode_stmt_list RBRACE' @@ -1149,7 +1149,7 @@ def buildOperandTypeMap(userDict, lineno): ctype = 'uint%d_t' % size is_signed = 0 elif desc == 'float': - is_signed = 1 # shouldn't really matter + is_signed = 1 # shouldn't really matter if size == 32: ctype = 'float' elif size == 64: @@ -1595,9 +1595,9 @@ def buildOperandNameMap(userDict, lineno): operands = userDict.keys() operandsREString = (r''' - (?size), nlu(0) @@ -91,7 +91,7 @@ TLB::lookup(Addr vpn, uint8_t asn) const Addr Mask = pte->Mask; Addr InvMask = ~Mask; Addr VPN = pte->VPN; - // warn("Valid: %d - %d\n",pte->V0,pte->V1); + // warn("Valid: %d - %d\n",pte->V0,pte->V1); if(((vpn & InvMask) == (VPN & InvMask)) && (pte->G || (asn == pte->asid))) { // We have a VPN + ASID Match retval = pte; @@ -389,7 +389,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) } else {// Ok, this is really a match, set paddr - // hits++; + // hits++; Addr PAddr; if(EvenOdd == 0){ PAddr = pte->PFN0; @@ -406,7 +406,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) } else { // Didn't find any match, return a TLB Refill Exception - // misses++; + // misses++; ItbRefillFault *Flt=new ItbRefillFault(); /* EntryHi VPN, ASID fields must be set */ Flt->EntryHi_Asid = Asid; @@ -494,7 +494,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) if(Valid == false) {//Invalid entry - // invalids++; + // invalids++; DtbInvalidFault *Flt = new DtbInvalidFault(); /* EntryHi VPN, ASID fields must be set */ Flt->EntryHi_Asid = Asid; @@ -512,7 +512,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) } else {// Ok, this is really a match, set paddr - // hits++; + // hits++; if(!Dirty) { TLBModifiedFault *Flt = new TLBModifiedFault(); @@ -544,7 +544,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) } else { // Didn't find any match, return a TLB Refill Exception - // misses++; + // misses++; DtbRefillFault *Flt=new DtbRefillFault(); /* EntryHi VPN, ASID fields must be set */ Flt->EntryHi_Asid = Asid; @@ -577,19 +577,19 @@ ITB::ITB(const Params *p) // ITB::regStats() // { // /* hits - causes failure for some reason -// .name(name() + ".hits") -// .desc("ITB hits"); +// .name(name() + ".hits") +// .desc("ITB hits"); // misses -// .name(name() + ".misses") -// .desc("ITB misses"); +// .name(name() + ".misses") +// .desc("ITB misses"); // acv -// .name(name() + ".acv") -// .desc("ITB acv"); +// .name(name() + ".acv") +// .desc("ITB acv"); // accesses -// .name(name() + ".accesses") -// .desc("ITB accesses"); +// .name(name() + ".accesses") +// .desc("ITB accesses"); -// accesses = hits + misses + invalids; */ +// accesses = hits + misses + invalids; */ // } diff --git a/src/arch/mips/tlb.hh b/src/arch/mips/tlb.hh index 4333777ff..feb2509c5 100644 --- a/src/arch/mips/tlb.hh +++ b/src/arch/mips/tlb.hh @@ -84,11 +84,11 @@ class TLB : public BaseTLB { protected: typedef std::multimap PageTable; - PageTable lookupTable; // Quick lookup into page table + PageTable lookupTable; // Quick lookup into page table - MipsISA::PTE *table; // the Page Table - int size; // TLB Size - int nlu; // not last used entry (for replacement) + MipsISA::PTE *table; // the Page Table + int size; // TLB Size + int nlu; // not last used entry (for replacement) void nextnlu() { if (++nlu >= size) nlu = 0; } MipsISA::PTE *lookup(Addr vpn, uint8_t asn) const; diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh index 133817eb5..30455792f 100644 --- a/src/arch/sparc/isa_traits.hh +++ b/src/arch/sparc/isa_traits.hh @@ -66,7 +66,7 @@ namespace SparcISA }; // semantically meaningful register indices - const int ZeroReg = 0; // architecturally meaningful + const int ZeroReg = 0; // architecturally meaningful // the rest of these depend on the ABI const int StackPointerReg = 14; const int ReturnAddressReg = 31; // post call, precall is 15 diff --git a/src/arch/sparc/linux/linux.cc b/src/arch/sparc/linux/linux.cc index 1211d5f65..102e5af3b 100644 --- a/src/arch/sparc/linux/linux.cc +++ b/src/arch/sparc/linux/linux.cc @@ -34,34 +34,34 @@ // open(2) flags translation table OpenFlagTransTable SparcLinux::openFlagTable[] = { #ifdef _MSC_VER - { SparcLinux::TGT_O_RDONLY, _O_RDONLY }, - { SparcLinux::TGT_O_WRONLY, _O_WRONLY }, - { SparcLinux::TGT_O_RDWR, _O_RDWR }, - { SparcLinux::TGT_O_APPEND, _O_APPEND }, - { SparcLinux::TGT_O_CREAT, _O_CREAT }, - { SparcLinux::TGT_O_TRUNC, _O_TRUNC }, - { SparcLinux::TGT_O_EXCL, _O_EXCL }, + { SparcLinux::TGT_O_RDONLY, _O_RDONLY }, + { SparcLinux::TGT_O_WRONLY, _O_WRONLY }, + { SparcLinux::TGT_O_RDWR, _O_RDWR }, + { SparcLinux::TGT_O_APPEND, _O_APPEND }, + { SparcLinux::TGT_O_CREAT, _O_CREAT }, + { SparcLinux::TGT_O_TRUNC, _O_TRUNC }, + { SparcLinux::TGT_O_EXCL, _O_EXCL }, #ifdef _O_NONBLOCK - { SparcLinux::TGT_O_NONBLOCK, _O_NONBLOCK }, + { SparcLinux::TGT_O_NONBLOCK, _O_NONBLOCK }, #endif #ifdef _O_NOCTTY - { SparcLinux::TGT_O_NOCTTY, _O_NOCTTY }, + { SparcLinux::TGT_O_NOCTTY, _O_NOCTTY }, #endif #ifdef _O_SYNC - { SparcLinux::TGT_O_SYNC, _O_SYNC }, + { SparcLinux::TGT_O_SYNC, _O_SYNC }, #endif #else /* !_MSC_VER */ - { SparcLinux::TGT_O_RDONLY, O_RDONLY }, - { SparcLinux::TGT_O_WRONLY, O_WRONLY }, - { SparcLinux::TGT_O_RDWR, O_RDWR }, - { SparcLinux::TGT_O_APPEND, O_APPEND }, - { SparcLinux::TGT_O_CREAT, O_CREAT }, - { SparcLinux::TGT_O_TRUNC, O_TRUNC }, - { SparcLinux::TGT_O_EXCL, O_EXCL }, - { SparcLinux::TGT_O_NONBLOCK, O_NONBLOCK }, - { SparcLinux::TGT_O_NOCTTY, O_NOCTTY }, + { SparcLinux::TGT_O_RDONLY, O_RDONLY }, + { SparcLinux::TGT_O_WRONLY, O_WRONLY }, + { SparcLinux::TGT_O_RDWR, O_RDWR }, + { SparcLinux::TGT_O_APPEND, O_APPEND }, + { SparcLinux::TGT_O_CREAT, O_CREAT }, + { SparcLinux::TGT_O_TRUNC, O_TRUNC }, + { SparcLinux::TGT_O_EXCL, O_EXCL }, + { SparcLinux::TGT_O_NONBLOCK, O_NONBLOCK }, + { SparcLinux::TGT_O_NOCTTY, O_NOCTTY }, #ifdef O_SYNC - { SparcLinux::TGT_O_SYNC, O_SYNC }, + { SparcLinux::TGT_O_SYNC, O_SYNC }, #endif #endif /* _MSC_VER */ }; diff --git a/src/arch/sparc/linux/linux.hh b/src/arch/sparc/linux/linux.hh index f396eb5cd..b1dc691ce 100644 --- a/src/arch/sparc/linux/linux.hh +++ b/src/arch/sparc/linux/linux.hh @@ -58,21 +58,21 @@ class SparcLinux : public Linux static OpenFlagTransTable openFlagTable[]; - static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY - static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY - static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR - static const int TGT_O_NONBLOCK = 0x00004000; //!< O_NONBLOCK - static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND - static const int TGT_O_CREAT = 0x00000200; //!< O_CREAT - static const int TGT_O_TRUNC = 0x00000400; //!< O_TRUNC - static const int TGT_O_EXCL = 0x00000800; //!< O_EXCL - static const int TGT_O_NOCTTY = 0x00008000; //!< O_NOCTTY - static const int TGT_O_SYNC = 0x00002000; //!< O_SYNC -// static const int TGT_O_DRD = 0x00010000; //!< O_DRD -// static const int TGT_O_DIRECTIO = 0x00020000; //!< O_DIRECTIO -// static const int TGT_O_CACHE = 0x00002000; //!< O_CACHE -// static const int TGT_O_DSYNC = 0x00008000; //!< O_DSYNC -// static const int TGT_O_RSYNC = 0x00040000; //!< O_RSYNC + static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY + static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY + static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR + static const int TGT_O_NONBLOCK = 0x00004000; //!< O_NONBLOCK + static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND + static const int TGT_O_CREAT = 0x00000200; //!< O_CREAT + static const int TGT_O_TRUNC = 0x00000400; //!< O_TRUNC + static const int TGT_O_EXCL = 0x00000800; //!< O_EXCL + static const int TGT_O_NOCTTY = 0x00008000; //!< O_NOCTTY + static const int TGT_O_SYNC = 0x00002000; //!< O_SYNC +// static const int TGT_O_DRD = 0x00010000; //!< O_DRD +// static const int TGT_O_DIRECTIO = 0x00020000; //!< O_DIRECTIO +// static const int TGT_O_CACHE = 0x00002000; //!< O_CACHE +// static const int TGT_O_DSYNC = 0x00008000; //!< O_DSYNC +// static const int TGT_O_RSYNC = 0x00040000; //!< O_RSYNC static const int NUM_OPEN_FLAGS; diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh index 3e17779a9..bf9c880fa 100644 --- a/src/arch/sparc/miscregfile.hh +++ b/src/arch/sparc/miscregfile.hh @@ -171,50 +171,50 @@ namespace SparcISA private: /* ASR Registers */ - //uint64_t y; // Y (used in obsolete multiplication) - //uint8_t ccr; // Condition Code Register - uint8_t asi; // Address Space Identifier - uint64_t tick; // Hardware clock-tick counter - uint8_t fprs; // Floating-Point Register State - uint64_t gsr; // General Status Register + //uint64_t y; // Y (used in obsolete multiplication) + //uint8_t ccr; // Condition Code Register + uint8_t asi; // Address Space Identifier + uint64_t tick; // Hardware clock-tick counter + uint8_t fprs; // Floating-Point Register State + uint64_t gsr; // General Status Register uint64_t softint; - uint64_t tick_cmpr; // Hardware tick compare registers - uint64_t stick; // Hardware clock-tick counter - uint64_t stick_cmpr; // Hardware tick compare registers + uint64_t tick_cmpr; // Hardware tick compare registers + uint64_t stick; // Hardware clock-tick counter + uint64_t stick_cmpr; // Hardware tick compare registers /* Privileged Registers */ - uint64_t tpc[MaxTL]; // Trap Program Counter (value from + uint64_t tpc[MaxTL]; // Trap Program Counter (value from // previous trap level) - uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from + uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from // previous trap level) - uint64_t tstate[MaxTL]; // Trap State - uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured + uint64_t tstate[MaxTL]; // Trap State + uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured // on the previous level) - uint64_t tba; // Trap Base Address - - uint16_t pstate; // Process State Register - uint8_t tl; // Trap Level - uint8_t pil; // Process Interrupt Register - uint8_t cwp; // Current Window Pointer - //uint8_t cansave; // Savable windows - //uint8_t canrestore; // Restorable windows - //uint8_t cleanwin; // Clean windows - //uint8_t otherwin; // Other windows - //uint8_t wstate; // Window State + uint64_t tba; // Trap Base Address + + uint16_t pstate; // Process State Register + uint8_t tl; // Trap Level + uint8_t pil; // Process Interrupt Register + uint8_t cwp; // Current Window Pointer + //uint8_t cansave; // Savable windows + //uint8_t canrestore; // Restorable windows + //uint8_t cleanwin; // Clean windows + //uint8_t otherwin; // Other windows + //uint8_t wstate; // Window State uint8_t gl; // Global level register /** Hyperprivileged Registers */ - uint64_t hpstate; // Hyperprivileged State Register + uint64_t hpstate; // Hyperprivileged State Register uint64_t htstate[MaxTL];// Hyperprivileged Trap State Register uint64_t hintp; - uint64_t htba; // Hyperprivileged Trap Base Address register - uint64_t hstick_cmpr; // Hardware tick compare registers + uint64_t htba; // Hyperprivileged Trap Base Address register + uint64_t hstick_cmpr; // Hardware tick compare registers uint64_t strandStatusReg;// Per strand status register /** Floating point misc registers. */ - uint64_t fsr; // Floating-Point State Register + uint64_t fsr; // Floating-Point State Register /** MMU Internal Registers */ uint16_t priContext; diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh index c03f69fc5..581785714 100644 --- a/src/arch/sparc/regfile.hh +++ b/src/arch/sparc/regfile.hh @@ -48,8 +48,8 @@ namespace SparcISA class RegFile { protected: - Addr pc; // Program Counter - Addr npc; // Next Program Counter + Addr pc; // Program Counter + Addr npc; // Next Program Counter Addr nnpc; public: @@ -63,9 +63,9 @@ namespace SparcISA void setNextNPC(Addr val); protected: - IntRegFile intRegFile; // integer register file - FloatRegFile floatRegFile; // floating point register file - MiscRegFile miscRegFile; // control register file + IntRegFile intRegFile; // integer register file + FloatRegFile floatRegFile; // floating point register file + MiscRegFile miscRegFile; // control register file public: diff --git a/src/arch/sparc/remote_gdb.cc b/src/arch/sparc/remote_gdb.cc index 67cc5b0d1..ef30bd808 100644 --- a/src/arch/sparc/remote_gdb.cc +++ b/src/arch/sparc/remote_gdb.cc @@ -30,7 +30,7 @@ /* * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. + * The Regents of the University of California. All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and @@ -38,8 +38,8 @@ * * All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Lawrence Berkeley Laboratories. + * This product includes software developed by the University of + * California, Lawrence Berkeley Laboratories. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -51,8 +51,8 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. + * This product includes software developed by the University of + * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -69,7 +69,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94 + * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94 */ /*- @@ -89,8 +89,8 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. * 4. Neither the name of The NetBSD Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. @@ -146,7 +146,7 @@ RemoteGDB::RemoteGDB(System *_system, ThreadContext *c) /////////////////////////////////////////////////////////// // RemoteGDB::acc // -// Determine if the mapping at va..(va+len) is valid. +// Determine if the mapping at va..(va+len) is valid. // bool RemoteGDB::acc(Addr va, size_t len) @@ -171,8 +171,8 @@ RemoteGDB::acc(Addr va, size_t len) /////////////////////////////////////////////////////////// // RemoteGDB::getregs // -// Translate the kernel debugger register format into -// the GDB register format. +// Translate the kernel debugger register format into +// the GDB register format. void RemoteGDB::getregs() { @@ -217,8 +217,8 @@ RemoteGDB::getregs() /////////////////////////////////////////////////////////// // RemoteGDB::setregs // -// Translate the GDB register format into the kernel -// debugger register format. +// Translate the GDB register format into the kernel +// debugger register format. // void RemoteGDB::setregs() diff --git a/src/arch/sparc/solaris/solaris.cc b/src/arch/sparc/solaris/solaris.cc index c53caa72a..3cc910005 100644 --- a/src/arch/sparc/solaris/solaris.cc +++ b/src/arch/sparc/solaris/solaris.cc @@ -35,40 +35,40 @@ // open(2) flags translation table OpenFlagTransTable SparcSolaris::openFlagTable[] = { #ifdef _MSC_VER - { SparcSolaris::TGT_O_RDONLY, _O_RDONLY }, - { SparcSolaris::TGT_O_WRONLY, _O_WRONLY }, - { SparcSolaris::TGT_O_RDWR, _O_RDWR }, - { SparcSolaris::TGT_O_APPEND, _O_APPEND }, - { SparcSolaris::TGT_O_CREAT, _O_CREAT }, - { SparcSolaris::TGT_O_TRUNC, _O_TRUNC }, - { SparcSolaris::TGT_O_EXCL, _O_EXCL }, + { SparcSolaris::TGT_O_RDONLY, _O_RDONLY }, + { SparcSolaris::TGT_O_WRONLY, _O_WRONLY }, + { SparcSolaris::TGT_O_RDWR, _O_RDWR }, + { SparcSolaris::TGT_O_APPEND, _O_APPEND }, + { SparcSolaris::TGT_O_CREAT, _O_CREAT }, + { SparcSolaris::TGT_O_TRUNC, _O_TRUNC }, + { SparcSolaris::TGT_O_EXCL, _O_EXCL }, #ifdef _O_NONBLOCK - { SparcSolaris::TGT_O_NONBLOCK, _O_NONBLOCK }, - { SparcSolaris::TGT_O_NDELAY , _O_NONBLOCK }, + { SparcSolaris::TGT_O_NONBLOCK, _O_NONBLOCK }, + { SparcSolaris::TGT_O_NDELAY , _O_NONBLOCK }, #endif #ifdef _O_NOCTTY - { SparcSolaris::TGT_O_NOCTTY, _O_NOCTTY }, + { SparcSolaris::TGT_O_NOCTTY, _O_NOCTTY }, #endif #ifdef _O_SYNC - { SparcSolaris::TGT_O_SYNC, _O_SYNC }, - { SparcSolaris::TGT_O_DSYNC, _O_SYNC }, - { SparcSolaris::TGT_O_RSYNC, _O_SYNC }, + { SparcSolaris::TGT_O_SYNC, _O_SYNC }, + { SparcSolaris::TGT_O_DSYNC, _O_SYNC }, + { SparcSolaris::TGT_O_RSYNC, _O_SYNC }, #endif #else /* !_MSC_VER */ - { SparcSolaris::TGT_O_RDONLY, O_RDONLY }, - { SparcSolaris::TGT_O_WRONLY, O_WRONLY }, - { SparcSolaris::TGT_O_RDWR, O_RDWR }, - { SparcSolaris::TGT_O_APPEND, O_APPEND }, - { SparcSolaris::TGT_O_CREAT, O_CREAT }, - { SparcSolaris::TGT_O_TRUNC, O_TRUNC }, - { SparcSolaris::TGT_O_EXCL, O_EXCL }, - { SparcSolaris::TGT_O_NONBLOCK, O_NONBLOCK }, - { SparcSolaris::TGT_O_NDELAY , O_NONBLOCK }, - { SparcSolaris::TGT_O_NOCTTY, O_NOCTTY }, + { SparcSolaris::TGT_O_RDONLY, O_RDONLY }, + { SparcSolaris::TGT_O_WRONLY, O_WRONLY }, + { SparcSolaris::TGT_O_RDWR, O_RDWR }, + { SparcSolaris::TGT_O_APPEND, O_APPEND }, + { SparcSolaris::TGT_O_CREAT, O_CREAT }, + { SparcSolaris::TGT_O_TRUNC, O_TRUNC }, + { SparcSolaris::TGT_O_EXCL, O_EXCL }, + { SparcSolaris::TGT_O_NONBLOCK, O_NONBLOCK }, + { SparcSolaris::TGT_O_NDELAY , O_NONBLOCK }, + { SparcSolaris::TGT_O_NOCTTY, O_NOCTTY }, #ifdef O_SYNC - { SparcSolaris::TGT_O_SYNC, O_SYNC }, - { SparcSolaris::TGT_O_DSYNC, O_SYNC }, - { SparcSolaris::TGT_O_RSYNC, O_SYNC }, + { SparcSolaris::TGT_O_SYNC, O_SYNC }, + { SparcSolaris::TGT_O_DSYNC, O_SYNC }, + { SparcSolaris::TGT_O_RSYNC, O_SYNC }, #endif #endif /* _MSC_VER */ }; diff --git a/src/arch/sparc/solaris/solaris.hh b/src/arch/sparc/solaris/solaris.hh index 0564faba4..df2565027 100644 --- a/src/arch/sparc/solaris/solaris.hh +++ b/src/arch/sparc/solaris/solaris.hh @@ -39,22 +39,22 @@ class SparcSolaris : public Solaris static OpenFlagTransTable openFlagTable[]; - static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY - static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY - static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR - static const int TGT_O_NDELAY = 0x00000004; //!< O_NONBLOCK - static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND + static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY + static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY + static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR + static const int TGT_O_NDELAY = 0x00000004; //!< O_NONBLOCK + static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND static const int TGT_O_SYNC = 0x00000010; //!< O_SYNC static const int TGT_O_DSYNC = 0x00000040; //!< O_SYNC static const int TGT_O_RSYNC = 0x00008000; //!< O_SYNC static const int TGT_O_NONBLOCK = 0x00000080; //!< O_NONBLOCK static const int TGT_O_PRIV = 0x00001000; //?? static const int TGT_O_LARGEFILE = 0x00002000; //?? - static const int TGT_O_CREAT = 0x00000100; //!< O_CREAT - static const int TGT_O_TRUNC = 0x00000200; //!< O_TRUNC - static const int TGT_O_EXCL = 0x00000400; //!< O_EXCL - static const int TGT_O_NOCTTY = 0x00000800; //!< O_NOCTTY - static const int TGT_O_XATTR = 0x00004000; //?? + static const int TGT_O_CREAT = 0x00000100; //!< O_CREAT + static const int TGT_O_TRUNC = 0x00000200; //!< O_TRUNC + static const int TGT_O_EXCL = 0x00000400; //!< O_EXCL + static const int TGT_O_NOCTTY = 0x00000800; //!< O_NOCTTY + static const int TGT_O_XATTR = 0x00004000; //?? static const int NUM_OPEN_FLAGS; diff --git a/src/arch/sparc/sparc_traits.hh b/src/arch/sparc/sparc_traits.hh index 715c08c03..e154ba274 100644 --- a/src/arch/sparc/sparc_traits.hh +++ b/src/arch/sparc/sparc_traits.hh @@ -47,8 +47,8 @@ namespace SparcISA // const int NumRegularIntRegs = MaxGL * 8 + NWindows * 16; // const int NumMicroIntRegs = 1; // const int NumIntRegs = -// NumRegularIntRegs + -// NumMicroIntRegs; +// NumRegularIntRegs + +// NumMicroIntRegs; // const int NumFloatRegs = 64; // const int NumMiscRegs = 40; } diff --git a/src/arch/x86/isa/insts/general_purpose/cache_and_memory_management.py b/src/arch/x86/isa/insts/general_purpose/cache_and_memory_management.py index b5fc43fcd..08b842825 100644 --- a/src/arch/x86/isa/insts/general_purpose/cache_and_memory_management.py +++ b/src/arch/x86/isa/insts/general_purpose/cache_and_memory_management.py @@ -56,17 +56,17 @@ microcode = "" #let {{ # class LFENCE(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class SFENCE(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class MFENCE(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class PREFETCHlevel(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class PREFETCH(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class PREFETCHW(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class CLFLUSH(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" #}}; diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/call.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/call.py index 45a7822fb..7abafe253 100644 --- a/src/arch/x86/isa/insts/general_purpose/control_transfer/call.py +++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/call.py @@ -103,5 +103,5 @@ def macroop CALL_NEAR_P ''' #let {{ # class CALL(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" #}}; diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py index 327361746..be562b424 100644 --- a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py +++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py @@ -239,7 +239,7 @@ def macroop IRET_VIRT { ''' #let {{ # class INT(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class INTO(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" #}}; diff --git a/src/arch/x86/isa/insts/general_purpose/data_conversion/ascii_adjust.py b/src/arch/x86/isa/insts/general_purpose/data_conversion/ascii_adjust.py index a1e322e56..2cbdd1ad8 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_conversion/ascii_adjust.py +++ b/src/arch/x86/isa/insts/general_purpose/data_conversion/ascii_adjust.py @@ -56,11 +56,11 @@ microcode = "" #let {{ # class AAA(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class AAD(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class AAM(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class AAS(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" #}}; diff --git a/src/arch/x86/isa/insts/general_purpose/data_conversion/bcd_adjust.py b/src/arch/x86/isa/insts/general_purpose/data_conversion/bcd_adjust.py index 213724768..d220fdeb6 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_conversion/bcd_adjust.py +++ b/src/arch/x86/isa/insts/general_purpose/data_conversion/bcd_adjust.py @@ -56,7 +56,7 @@ microcode = "" #let {{ # class DAA(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class DAS(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" #}}; diff --git a/src/arch/x86/isa/insts/general_purpose/data_conversion/endian_conversion.py b/src/arch/x86/isa/insts/general_purpose/data_conversion/endian_conversion.py index b98d09816..b375ac27e 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_conversion/endian_conversion.py +++ b/src/arch/x86/isa/insts/general_purpose/data_conversion/endian_conversion.py @@ -56,5 +56,5 @@ microcode = "" #let {{ # class BSWAP(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" #}}; diff --git a/src/arch/x86/isa/insts/general_purpose/data_conversion/extract_sign_mask.py b/src/arch/x86/isa/insts/general_purpose/data_conversion/extract_sign_mask.py index 1e0810594..01fa280fc 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_conversion/extract_sign_mask.py +++ b/src/arch/x86/isa/insts/general_purpose/data_conversion/extract_sign_mask.py @@ -56,7 +56,7 @@ microcode = "" #let {{ # class MOVMSKPS(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class MOVMSKPD(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" #}}; diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py index 35f0436f5..d965735f5 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py @@ -342,7 +342,7 @@ processDescriptor: ''' #let {{ # class MOVD(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class MOVNTI(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" #}}; diff --git a/src/arch/x86/isa/insts/general_purpose/load_segment_registers.py b/src/arch/x86/isa/insts/general_purpose/load_segment_registers.py index 8aec4b99e..e6633ee1a 100644 --- a/src/arch/x86/isa/insts/general_purpose/load_segment_registers.py +++ b/src/arch/x86/isa/insts/general_purpose/load_segment_registers.py @@ -56,17 +56,17 @@ microcode = "" #let {{ # class LDS(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class LES(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class LFS(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class LGS(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class LSS(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class MOV_SEG(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class POP(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" #}}; diff --git a/src/arch/x86/isa/insts/general_purpose/semaphores.py b/src/arch/x86/isa/insts/general_purpose/semaphores.py index 27a31dbd9..da16477fc 100644 --- a/src/arch/x86/isa/insts/general_purpose/semaphores.py +++ b/src/arch/x86/isa/insts/general_purpose/semaphores.py @@ -81,7 +81,7 @@ def macroop CMPXCHG_P_R { ''' #let {{ # class XADD(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class XCHG(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" #}}; diff --git a/src/arch/x86/isa/insts/general_purpose/system_calls.py b/src/arch/x86/isa/insts/general_purpose/system_calls.py index e056bea84..b3a57eca9 100644 --- a/src/arch/x86/isa/insts/general_purpose/system_calls.py +++ b/src/arch/x86/isa/insts/general_purpose/system_calls.py @@ -56,11 +56,11 @@ microcode = "" #let {{ # class SYSENTER(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class SYSEXIT(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class SYSCALL(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" # class SYSRET(Inst): -# "GenFault ${new UnimpInstFault}" +# "GenFault ${new UnimpInstFault}" #}}; diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh index 8d6468f06..dbc336da1 100644 --- a/src/arch/x86/linux/linux.hh +++ b/src/arch/x86/linux/linux.hh @@ -87,21 +87,21 @@ class X86Linux64 : public Linux static OpenFlagTransTable openFlagTable[]; - static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY - static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY - static const int TGT_O_RDWR = 00000002; //!< O_RDWR - static const int TGT_O_NONBLOCK = 00004000; //!< O_NONBLOCK - static const int TGT_O_APPEND = 00002000; //!< O_APPEND - static const int TGT_O_CREAT = 00000100; //!< O_CREAT - static const int TGT_O_TRUNC = 00001000; //!< O_TRUNC - static const int TGT_O_EXCL = 00000200; //!< O_EXCL - static const int TGT_O_NOCTTY = 00000400; //!< O_NOCTTY - static const int TGT_O_SYNC = 00010000; //!< O_SYNC -// static const int TGT_O_DRD = 0x00010000; //!< O_DRD -// static const int TGT_O_DIRECTIO = 0x00020000; //!< O_DIRECTIO -// static const int TGT_O_CACHE = 0x00002000; //!< O_CACHE -// static const int TGT_O_DSYNC = 0x00008000; //!< O_DSYNC -// static const int TGT_O_RSYNC = 0x00040000; //!< O_RSYNC + static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY + static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY + static const int TGT_O_RDWR = 00000002; //!< O_RDWR + static const int TGT_O_NONBLOCK = 00004000; //!< O_NONBLOCK + static const int TGT_O_APPEND = 00002000; //!< O_APPEND + static const int TGT_O_CREAT = 00000100; //!< O_CREAT + static const int TGT_O_TRUNC = 00001000; //!< O_TRUNC + static const int TGT_O_EXCL = 00000200; //!< O_EXCL + static const int TGT_O_NOCTTY = 00000400; //!< O_NOCTTY + static const int TGT_O_SYNC = 00010000; //!< O_SYNC +// static const int TGT_O_DRD = 0x00010000; //!< O_DRD +// static const int TGT_O_DIRECTIO = 0x00020000; //!< O_DIRECTIO +// static const int TGT_O_CACHE = 0x00002000; //!< O_CACHE +// static const int TGT_O_DSYNC = 0x00008000; //!< O_DSYNC +// static const int TGT_O_RSYNC = 0x00040000; //!< O_RSYNC static const int NUM_OPEN_FLAGS; diff --git a/src/arch/x86/remote_gdb.cc b/src/arch/x86/remote_gdb.cc index 5ab0ec3fb..3a024e087 100644 --- a/src/arch/x86/remote_gdb.cc +++ b/src/arch/x86/remote_gdb.cc @@ -57,7 +57,7 @@ /* * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. + * The Regents of the University of California. All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and @@ -65,8 +65,8 @@ * * All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Lawrence Berkeley Laboratories. + * This product includes software developed by the University of + * California, Lawrence Berkeley Laboratories. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -78,8 +78,8 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. + * This product includes software developed by the University of + * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -96,7 +96,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94 + * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94 */ /*- @@ -116,8 +116,8 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. * 4. Neither the name of The NetBSD Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. -- cgit v1.2.3 From 4826610d8604e8ce828ebefd9d25f5ef637c3630 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 19 Sep 2008 09:42:54 -0700 Subject: We're using the static keyword improperly in some cases. --- src/arch/alpha/utility.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/alpha/utility.hh b/src/arch/alpha/utility.hh index 11357bc44..ddbf88e95 100644 --- a/src/arch/alpha/utility.hh +++ b/src/arch/alpha/utility.hh @@ -44,7 +44,7 @@ namespace AlphaISA uint64_t getArgument(ThreadContext *tc, int number, bool fp); - static inline bool + inline bool inUserMode(ThreadContext *tc) { return (tc->readMiscRegNoEffect(AlphaISA::IPR_DTB_CM) & 0x18) != 0; -- cgit v1.2.3 From f3f4b17c5b6f594524d54176c15c23d6338c60a4 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 22 Sep 2008 08:21:47 -0700 Subject: style --- src/arch/alpha/utility.hh | 50 ++++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 20 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/utility.hh b/src/arch/alpha/utility.hh index ddbf88e95..43d4908b4 100644 --- a/src/arch/alpha/utility.hh +++ b/src/arch/alpha/utility.hh @@ -41,7 +41,6 @@ namespace AlphaISA { - uint64_t getArgument(ThreadContext *tc, int number, bool fp); inline bool @@ -50,58 +49,71 @@ namespace AlphaISA return (tc->readMiscRegNoEffect(AlphaISA::IPR_DTB_CM) & 0x18) != 0; } - inline bool isCallerSaveIntegerRegister(unsigned int reg) { + inline bool + isCallerSaveIntegerRegister(unsigned int reg) + { panic("register classification not implemented"); return (reg >= 1 && reg <= 8 || reg >= 22 && reg <= 25 || reg == 27); } - inline bool isCalleeSaveIntegerRegister(unsigned int reg) { + inline bool + isCalleeSaveIntegerRegister(unsigned int reg) + { panic("register classification not implemented"); return (reg >= 9 && reg <= 15); } - inline bool isCallerSaveFloatRegister(unsigned int reg) { + inline bool + isCallerSaveFloatRegister(unsigned int reg) + { panic("register classification not implemented"); return false; } - inline bool isCalleeSaveFloatRegister(unsigned int reg) { + inline bool + isCalleeSaveFloatRegister(unsigned int reg) + { panic("register classification not implemented"); return false; } - inline Addr alignAddress(const Addr &addr, - unsigned int nbytes) { + inline Addr + alignAddress(const Addr &addr, unsigned int nbytes) + { return (addr & ~(nbytes - 1)); } // Instruction address compression hooks - inline Addr realPCToFetchPC(const Addr &addr) { + inline Addr + realPCToFetchPC(const Addr &addr) + { return addr; } - inline Addr fetchPCToRealPC(const Addr &addr) { + inline Addr + fetchPCToRealPC(const Addr &addr) + { return addr; } // the size of "fetched" instructions (not necessarily the size // of real instructions for PISA) - inline size_t fetchInstSize() { + inline size_t + fetchInstSize() + { return sizeof(MachInst); } - inline MachInst makeRegisterCopy(int dest, int src) { + inline MachInst + makeRegisterCopy(int dest, int src) + { panic("makeRegisterCopy not implemented"); return 0; } // Machine operations - - void saveMachineReg(AnyReg &savereg, const RegFile ®_file, - int regnum); - - void restoreMachineReg(RegFile ®s, const AnyReg ®, - int regnum); + void saveMachineReg(AnyReg &savereg, const RegFile ®_file, int regnum); + void restoreMachineReg(RegFile ®s, const AnyReg ®, int regnum); /** * Function to insure ISA semantics about 0 registers. @@ -112,9 +124,7 @@ namespace AlphaISA // Alpha IPR register accessors inline bool PcPAL(Addr addr) { return addr & 0x3; } - inline void startupCPU(ThreadContext *tc, int cpuId) { - tc->activate(0); - } + inline void startupCPU(ThreadContext *tc, int cpuId) { tc->activate(0); } //////////////////////////////////////////////////////////////////////// // -- cgit v1.2.3 From 70ec46de1736ef218ee0f554358c0558d56169ac Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 23 Sep 2008 20:38:02 -0700 Subject: sparc: Fix style, create a helper function for translation. The translate function simplifies code and removes some compiler warnings in gcc 3.4 --- src/arch/sparc/pagetable.hh | 119 ++++++++++++++++++++++++++++---------------- src/arch/sparc/tlb.cc | 100 ++++++++++++++++--------------------- src/arch/sparc/tlb.hh | 6 +-- 3 files changed, 123 insertions(+), 102 deletions(-) (limited to 'src/arch') diff --git a/src/arch/sparc/pagetable.hh b/src/arch/sparc/pagetable.hh index bf7f34b60..d787f30e4 100644 --- a/src/arch/sparc/pagetable.hh +++ b/src/arch/sparc/pagetable.hh @@ -38,8 +38,8 @@ class Checkpoint; -namespace SparcISA -{ +namespace SparcISA { + struct VAddr { VAddr(Addr a) { panic("not implemented yet."); } @@ -54,8 +54,15 @@ class TteTag public: TteTag() : entry(0), populated(false) {} TteTag(uint64_t e) : entry(e), populated(true) {} - const TteTag &operator=(uint64_t e) { populated = true; - entry = e; return *this; } + + const TteTag & + operator=(uint64_t e) + { + populated = true; + entry = e; + return *this; + } + bool valid() const {assert(populated); return !bits(entry,62,62); } Addr va() const {assert(populated); return bits(entry,41,0); } }; @@ -76,13 +83,13 @@ class PageTableEntry uint64_t entry4u; bool populated; - public: - PageTableEntry() : entry(0), type(invalid), populated(false) {} + PageTableEntry() + : entry(0), type(invalid), populated(false) + {} PageTableEntry(uint64_t e, EntryType t = sun4u) : entry(e), type(t), populated(true) - { populate(entry, type); } @@ -113,49 +120,74 @@ class PageTableEntry } } - void clear() + void + clear() { populated = false; } static int pageSizes[6]; - uint64_t operator()() const { assert(populated); return entry4u; } - const PageTableEntry &operator=(uint64_t e) { populated = true; - entry4u = e; return *this; } - - const PageTableEntry &operator=(const PageTableEntry &e) - { populated = true; entry4u = e.entry4u; type = e.type; return *this; } - - bool valid() const { return bits(entry4u,63,63) && populated; } - uint8_t _size() const { assert(populated); - return bits(entry4u, 62,61) | - bits(entry4u, 48,48) << 2; } - Addr size() const { assert(_size() < 6); return pageSizes[_size()]; } - Addr sizeMask() const { assert(_size() < 6); return pageSizes[_size()]-1;} - bool ie() const { return bits(entry4u, 59,59); } - Addr pfn() const { assert(populated); return bits(entry4u,39,13); } - Addr paddr() const { assert(populated); return mbits(entry4u, 39,13);} - bool locked() const { assert(populated); return bits(entry4u,6,6); } - bool cv() const { assert(populated); return bits(entry4u,4,4); } - bool cp() const { assert(populated); return bits(entry4u,5,5); } - bool priv() const { assert(populated); return bits(entry4u,2,2); } - bool writable() const { assert(populated); return bits(entry4u,1,1); } - bool nofault() const { assert(populated); return bits(entry4u,60,60); } - bool sideffect() const { assert(populated); return bits(entry4u,3,3); } - Addr paddrMask() const { assert(populated); - return mbits(entry4u, 39,13) & ~sizeMask(); } + const PageTableEntry & + operator=(uint64_t e) + { + populated = true; + entry4u = e; + return *this; + } + + const PageTableEntry & + operator=(const PageTableEntry &e) + { + populated = true; + entry4u = e.entry4u; + type = e.type; + return *this; + } + + bool valid() const { return bits(entry4u,63,63) && populated; } + + uint8_t + _size() const + { + assert(populated); + return bits(entry4u, 62,61) | bits(entry4u, 48,48) << 2; + } + + Addr size() const { assert(_size() < 6); return pageSizes[_size()]; } + Addr sizeMask() const { return size() - 1; } + bool ie() const { return bits(entry4u, 59,59); } + Addr pfn() const { assert(populated); return bits(entry4u,39,13); } + Addr paddr() const { assert(populated); return mbits(entry4u, 39,13);} + bool locked() const { assert(populated); return bits(entry4u,6,6); } + bool cv() const { assert(populated); return bits(entry4u,4,4); } + bool cp() const { assert(populated); return bits(entry4u,5,5); } + bool priv() const { assert(populated); return bits(entry4u,2,2); } + bool writable() const { assert(populated); return bits(entry4u,1,1); } + bool nofault() const { assert(populated); return bits(entry4u,60,60); } + bool sideffect() const { assert(populated); return bits(entry4u,3,3); } + Addr paddrMask() const { assert(populated); return paddr() & ~sizeMask(); } + + Addr + translate(Addr vaddr) const + { + assert(populated); + Addr mask = sizeMask(); + return (paddr() & ~mask) | (vaddr & mask); + } }; -struct TlbRange { +struct TlbRange +{ Addr va; Addr size; int contextId; int partitionId; bool real; - inline bool operator<(const TlbRange &r2) const + inline bool + operator<(const TlbRange &r2) const { if (real && !r2.real) return true; @@ -178,7 +210,9 @@ struct TlbRange { return true; return false; } - inline bool operator==(const TlbRange &r2) const + + inline bool + operator==(const TlbRange &r2) const { return va == r2.va && size == r2.size && @@ -189,7 +223,11 @@ struct TlbRange { }; -struct TlbEntry { +struct TlbEntry +{ + TlbEntry() + {} + TlbEntry(Addr asn, Addr vaddr, Addr paddr) { uint64_t entry = 0; @@ -215,8 +253,7 @@ struct TlbEntry { valid = true; } - TlbEntry() - {} + TlbRange range; PageTableEntry pte; bool used; @@ -229,11 +266,9 @@ struct TlbEntry { void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); - }; - -}; // namespace SparcISA +} // namespace SparcISA #endif // __ARCH_SPARC_PAGE_TABLE_HH__ diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index 22df44908..defa33c51 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -51,7 +51,7 @@ TLB::TLB(const Params *p) { // To make this work you'll have to change the hypervisor and OS if (size > 64) - fatal("SPARC T1 TLB registers don't support more than 64 TLB entries."); + fatal("SPARC T1 TLB registers don't support more than 64 TLB entries"); tlb = new TlbEntry[size]; std::memset(tlb, 0, sizeof(TlbEntry) * size); @@ -87,8 +87,6 @@ void TLB::insert(Addr va, int partition_id, int context_id, bool real, const PageTableEntry& PTE, int entry) { - - MapIter i; TlbEntry *new_entry = NULL; // TlbRange tr; @@ -103,8 +101,9 @@ TLB::insert(Addr va, int partition_id, int context_id, bool real, tr.real = real; */ - DPRINTF(TLB, "TLB: Inserting TLB Entry; va=%#x pa=%#x pid=%d cid=%d r=%d entryid=%d\n", - va, PTE.paddr(), partition_id, context_id, (int)real, entry); + DPRINTF(TLB, + "TLB: Inserting Entry; va=%#x pa=%#x pid=%d cid=%d r=%d entryid=%d\n", + va, PTE.paddr(), partition_id, context_id, (int)real, entry); // Demap any entry that conflicts for (x = 0; x < size; x++) { @@ -128,7 +127,6 @@ TLB::insert(Addr va, int partition_id, int context_id, bool real, } } - /* i = lookupTable.find(tr); if (i != lookupTable.end()) { @@ -195,25 +193,22 @@ insertAllLocked: new_entry->valid = true; usedEntries++; - - i = lookupTable.insert(new_entry->range, new_entry); assert(i != lookupTable.end()); - // If all entries have there used bit set, clear it on them all, but the - // one we just inserted + // If all entries have their used bit set, clear it on them all, + // but the one we just inserted if (usedEntries == size) { clearUsedBits(); new_entry->used = true; usedEntries++; } - } TlbEntry* -TLB::lookup(Addr va, int partition_id, bool real, int context_id, bool - update_used) +TLB::lookup(Addr va, int partition_id, bool real, int context_id, + bool update_used) { MapIter i; TlbRange tr; @@ -240,8 +235,8 @@ TLB::lookup(Addr va, int partition_id, bool real, int context_id, bool DPRINTF(TLB, "TLB: Valid entry found pa: %#x size: %#x\n", t->pte.paddr(), t->pte.size()); - // Update the used bits only if this is a real access (not a fake one from - // virttophys() + // Update the used bits only if this is a real access (not a fake + // one from virttophys() if (!t->used && update_used) { t->used = true; usedEntries++; @@ -304,11 +299,10 @@ TLB::demapPage(Addr va, int partition_id, bool real, int context_id) void TLB::demapContext(int partition_id, int context_id) { - int x; DPRINTF(IPR, "TLB: Demapping Context pid=%#d cid=%d\n", partition_id, context_id); cacheValid = false; - for (x = 0; x < size; x++) { + for (int x = 0; x < size; x++) { if (tlb[x].range.contextId == context_id && tlb[x].range.partitionId == partition_id) { if (tlb[x].valid == true) { @@ -327,10 +321,9 @@ TLB::demapContext(int partition_id, int context_id) void TLB::demapAll(int partition_id) { - int x; DPRINTF(TLB, "TLB: Demapping All pid=%#d\n", partition_id); cacheValid = false; - for (x = 0; x < size; x++) { + for (int x = 0; x < size; x++) { if (tlb[x].valid && !tlb[x].pte.locked() && tlb[x].range.partitionId == partition_id) { freeList.push_front(&tlb[x]); @@ -347,11 +340,10 @@ TLB::demapAll(int partition_id) void TLB::invalidateAll() { - int x; cacheValid = false; - lookupTable.clear(); - for (x = 0; x < size; x++) { + + for (int x = 0; x < size; x++) { if (tlb[x].valid == true) freeList.push_back(&tlb[x]); tlb[x].valid = false; @@ -361,7 +353,8 @@ TLB::invalidateAll() } uint64_t -TLB::TteRead(int entry) { +TLB::TteRead(int entry) +{ if (entry >= size) panic("entry: %d\n", entry); @@ -373,7 +366,8 @@ TLB::TteRead(int entry) { } uint64_t -TLB::TagRead(int entry) { +TLB::TagRead(int entry) +{ assert(entry < size); uint64_t tag; if (!tlb[entry].valid) @@ -459,9 +453,8 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) if (cacheEntry) { if (cacheEntry->range.va < vaddr + sizeof(MachInst) && cacheEntry->range.va + cacheEntry->range.size >= vaddr) { - req->setPaddr(cacheEntry->pte.paddr() & ~(cacheEntry->pte.size()-1) | - vaddr & cacheEntry->pte.size()-1 ); - return NoFault; + req->setPaddr(cacheEntry->pte.translate(vaddr)); + return NoFault; } } else { req->setPaddr(vaddr & PAddrImplMask); @@ -550,18 +543,18 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) cacheState = tlbdata; cacheEntry = e; - req->setPaddr(e->pte.paddr() & ~(e->pte.size()-1) | - vaddr & e->pte.size()-1 ); + req->setPaddr(e->pte.translate(vaddr)); DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); return NoFault; } - - Fault DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) { - /* @todo this could really use some profiling and fixing to make it faster! */ + /* + * @todo this could really use some profiling and fixing to make + * it faster! + */ uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA); Addr vaddr = req->getVaddr(); Addr size = req->getSize(); @@ -599,11 +592,11 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) if (cacheAsi[0] == asi && ce_va < vaddr + size && ce_va + ce->range.size > vaddr && (!write || ce->pte.writable())) { - req->setPaddr(ce->pte.paddrMask() | vaddr & ce->pte.sizeMask()); - if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1) - req->setFlags(req->getFlags() | UNCACHEABLE); - DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); - return NoFault; + req->setPaddr(ce->pte.translate(vaddr)); + if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1) + req->setFlags(req->getFlags() | UNCACHEABLE); + DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); + return NoFault; } // if matched } // if cache entry valid if (cacheEntry[1]) { @@ -612,11 +605,11 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) if (cacheAsi[1] == asi && ce_va < vaddr + size && ce_va + ce->range.size > vaddr && (!write || ce->pte.writable())) { - req->setPaddr(ce->pte.paddrMask() | vaddr & ce->pte.sizeMask()); - if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1) - req->setFlags(req->getFlags() | UNCACHEABLE); - DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); - return NoFault; + req->setPaddr(ce->pte.translate(vaddr)); + if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1) + req->setFlags(req->getFlags() | UNCACHEABLE); + DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); + return NoFault; } // if matched } // if cache entry valid } @@ -639,7 +632,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) TlbEntry *e; DPRINTF(TLB, "TLB: priv:%d hpriv:%d red:%d lsudm:%d part_id: %#X\n", - priv, hpriv, red, lsu_dm, part_id); + priv, hpriv, red, lsu_dm, part_id); if (implicit) { if (tl > 0) { @@ -725,11 +718,10 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) return new DataAccessException; } - if ((!lsu_dm && !hpriv && !red) || AsiIsReal(asi)) { real = true; context = 0; - }; + } if (hpriv && (implicit || (!AsiIsAsIfUser(asi) && !AsiIsReal(asi)))) { req->setPaddr(vaddr & PAddrImplMask); @@ -776,7 +768,6 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) return new DataAccessException; } - if (e->pte.sideffect() || (e->pte.paddr() >> 39) & 1) req->setFlags(req->getFlags() | UNCACHEABLE); @@ -796,8 +787,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) cacheAsi[0] = (ASI)0; } cacheValid = true; - req->setPaddr(e->pte.paddr() & ~(e->pte.size()-1) | - vaddr & e->pte.size()-1); + req->setPaddr(e->pte.translate(vaddr)); DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); return NoFault; @@ -869,7 +859,7 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) DPRINTF(IPR, "Memory Mapped IPR Read: asi=%#X a=%#x\n", (uint32_t)pkt->req->getAsi(), pkt->getAddr()); - ITB * itb = tc->getITBPtr(); + ITB *itb = tc->getITBPtr(); switch (asi) { case ASI_LSU_CONTROL_REG: @@ -1055,7 +1045,7 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) DPRINTF(IPR, "Memory Mapped IPR Write: asi=%#X a=%#x d=%#X\n", (uint32_t)asi, va, data); - ITB * itb = tc->getITBPtr(); + ITB *itb = tc->getITBPtr(); switch (asi) { case ASI_LSU_CONTROL_REG: @@ -1173,7 +1163,8 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) real_insert = bits(va, 9,9); pte.populate(data, bits(va,10,10) ? PageTableEntry::sun4v : PageTableEntry::sun4u); - insert(va_insert, part_insert, ct_insert, real_insert, pte, entry_insert); + insert(va_insert, part_insert, ct_insert, real_insert, pte, + entry_insert); break; case ASI_IMMU_DEMAP: ignore = false; @@ -1272,7 +1263,7 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) tc->getSystemPtr()->threadContexts[bits(data,12,8)]->getCpuPtr()-> post_interrupt(bits(data,5,0),0); break; - default: + default: doMmuWriteError: panic("need to impl DTB::doMmuRegWrite() got asi=%#x, va=%#x d=%#x\n", (uint32_t)pkt->req->getAsi(), pkt->getAddr(), data); @@ -1310,10 +1301,6 @@ DTB::GetTsbPtr(ThreadContext *tc, Addr addr, int ctx, Addr *ptrs) itb->cx_config); } - - - - uint64_t DTB::MakeTsbPtr(TsbPageSize ps, uint64_t tag_access, uint64_t c0_tsb, uint64_t c0_config, uint64_t cX_tsb, uint64_t cX_config) @@ -1341,7 +1328,6 @@ DTB::MakeTsbPtr(TsbPageSize ps, uint64_t tag_access, uint64_t c0_tsb, return ptr; } - void TLB::serialize(std::ostream &os) { diff --git a/src/arch/sparc/tlb.hh b/src/arch/sparc/tlb.hh index 2f7d08320..504a40cbb 100644 --- a/src/arch/sparc/tlb.hh +++ b/src/arch/sparc/tlb.hh @@ -109,9 +109,9 @@ class TLB : public BaseTLB * @param paritition_id partition this entry is for * @param real is this a real->phys or virt->phys translation * @param context_id if this is virt->phys what context - * @param update_used should ew update the used bits in the entries on not - * useful if we are trying to do a va->pa without mucking with any state for - * a debug read for example. + * @param update_used should ew update the used bits in the + * entries on not useful if we are trying to do a va->pa without + * mucking with any state for a debug read for example. * @return A pointer to a tlb entry */ TlbEntry *lookup(Addr va, int partition_id, bool real, int context_id = 0, -- cgit v1.2.3 From 0309c877f32d415122cfb59960ec41dba54ba3e3 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 26 Sep 2008 08:18:53 -0700 Subject: style: These files didn't even come close to following the M5 style guide. --- src/arch/mips/dsp.cc | 989 +++++++++++++++++++++++++-------------------------- src/arch/mips/dsp.hh | 285 ++++++++------- 2 files changed, 635 insertions(+), 639 deletions(-) (limited to 'src/arch') diff --git a/src/arch/mips/dsp.cc b/src/arch/mips/dsp.cc index 8e2db3f0b..183016ee7 100755 --- a/src/arch/mips/dsp.cc +++ b/src/arch/mips/dsp.cc @@ -40,92 +40,84 @@ using namespace MipsISA; using namespace std; int32_t -MipsISA::bitrev( int32_t value ) +MipsISA::bitrev(int32_t value) { int32_t result = 0; - int i, shift; + int shift; - for( i=0; i<16; i++ ) - { - shift = 2*i - 15; + for (int i = 0; i < 16; i++) { + shift = 2 * i - 15; - if( shift < 0 ) - result |= (value & 1L<> shift; + result |= (value & 1 << i) >> shift; } return result; } uint64_t -MipsISA::dspSaturate( uint64_t value, int32_t fmt, int32_t sign, uint32_t *overflow ) +MipsISA::dspSaturate(uint64_t value, int32_t fmt, int32_t sign, + uint32_t *overflow) { - int64_t svalue; + int64_t svalue = (int64_t)value; - svalue = (int64_t)value; - - switch( sign ) - { + switch(sign) { case SIGNED: - if( svalue > (int64_t)FIXED_SMAX[fmt] ) - { + if (svalue > (int64_t)FIXED_SMAX[fmt]) { *overflow = 1; svalue = (int64_t)FIXED_SMAX[fmt]; - } - else if( svalue < (int64_t)FIXED_SMIN[fmt] ) - { + } else if (svalue < (int64_t)FIXED_SMIN[fmt]) { *overflow = 1; svalue = (int64_t)FIXED_SMIN[fmt]; } break; case UNSIGNED: - if( svalue > (int64_t)FIXED_UMAX[fmt] ) - { + if (svalue > (int64_t)FIXED_UMAX[fmt]) { *overflow = 1; svalue = FIXED_UMAX[fmt]; - } - else if( svalue < (int64_t)FIXED_UMIN[fmt] ) - { + } else if (svalue < (int64_t)FIXED_UMIN[fmt]) { *overflow = 1; svalue = FIXED_UMIN[fmt]; } break; } - return( (uint64_t)svalue ); + return (uint64_t)svalue; } uint64_t -MipsISA::checkOverflow( uint64_t value, int32_t fmt, int32_t sign, uint32_t *overflow ) +MipsISA::checkOverflow(uint64_t value, int32_t fmt, int32_t sign, + uint32_t *overflow) { - int64_t svalue; - - svalue = (int64_t)value; + int64_t svalue = (int64_t)value; - switch( sign ) + switch(sign) { case SIGNED: - if( svalue > (int64_t)FIXED_SMAX[fmt] || svalue < (int64_t)FIXED_SMIN[fmt] ) + if (svalue > (int64_t)FIXED_SMAX[fmt] || + svalue < (int64_t)FIXED_SMIN[fmt]) *overflow = 1; break; case UNSIGNED: - if( svalue > (int64_t)FIXED_UMAX[fmt] || svalue < (int64_t)FIXED_UMIN[fmt] ) + if (svalue > (int64_t)FIXED_UMAX[fmt] || + svalue < (int64_t)FIXED_UMIN[fmt]) *overflow = 1; break; } - return( (uint64_t)svalue ); + return (uint64_t)svalue; } uint64_t -MipsISA::signExtend( uint64_t value, int32_t fmt ) +MipsISA::signExtend(uint64_t value, int32_t fmt) { int32_t signpos = SIMD_NBITS[fmt]; - uint64_t sign = uint64_t(1)<<(signpos-1); + uint64_t sign = uint64_t(1) << (signpos - 1); uint64_t ones = ~(0ULL); - if( value & sign ) + if (value & sign) value |= (ones << signpos); // extend with ones else value &= (ones >> (64 - signpos)); // extend with zeros @@ -134,231 +126,230 @@ MipsISA::signExtend( uint64_t value, int32_t fmt ) } uint64_t -MipsISA::addHalfLsb( uint64_t value, int32_t lsbpos ) +MipsISA::addHalfLsb(uint64_t value, int32_t lsbpos) { - return( value += ULL(1) << (lsbpos-1) ); + return value += ULL(1) << (lsbpos - 1); } int32_t -MipsISA::dspAbs( int32_t a, int32_t fmt, uint32_t *dspctl ) +MipsISA::dspAbs(int32_t a, int32_t fmt, uint32_t *dspctl) { - int i = 0; int nvals = SIMD_NVALS[fmt]; int32_t result; int64_t svalue; uint32_t ouflag = 0; uint64_t a_values[SIMD_MAX_VALS]; - simdUnpack( a, a_values, fmt, SIGNED ); + simdUnpack(a, a_values, fmt, SIGNED); - for( i=0; i> 1; + for (int i = 0; i < nvals; i++) { + if (round) + a_values[i] = addHalfLsb(a_values[i] + b_values[i], 1) >> 1; else - a_values[i] = ( a_values[i] + b_values[i] ) >> 1; + a_values[i] = (a_values[i] + b_values[i]) >> 1; } - simdPack( a_values, &result, fmt ); + simdPack(a_values, &result, fmt); - return( result ); + return result; } int32_t -MipsISA::dspSub( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl ) +MipsISA::dspSub(int32_t a, int32_t b, int32_t fmt, int32_t saturate, + int32_t sign, uint32_t *dspctl) { - int i = 0; int nvals = SIMD_NVALS[fmt]; int32_t result; uint32_t ouflag = 0; uint64_t a_values[SIMD_MAX_VALS]; uint64_t b_values[SIMD_MAX_VALS]; - simdUnpack( a, a_values, fmt, sign ); - simdUnpack( b, b_values, fmt, sign ); + simdUnpack(a, a_values, fmt, sign); + simdUnpack(b, b_values, fmt, sign); - for( i=0; i> 1; + if (round) + a_values[i] = addHalfLsb(a_values[i] - b_values[i], 1) >> 1; else - a_values[i] = ( a_values[i] - b_values[i] ) >> 1; + a_values[i] = (a_values[i] - b_values[i]) >> 1; } - simdPack( a_values, &result, fmt ); + simdPack(a_values, &result, fmt); - return( result ); + return result; } int32_t -MipsISA::dspShll( int32_t a, uint32_t sa, int32_t fmt, int32_t saturate, int32_t sign, uint32_t *dspctl ) +MipsISA::dspShll(int32_t a, uint32_t sa, int32_t fmt, int32_t saturate, + int32_t sign, uint32_t *dspctl) { - int i = 0; int nvals = SIMD_NVALS[fmt]; int32_t result; uint32_t ouflag = 0; uint64_t a_values[SIMD_MAX_VALS]; - sa = bits( sa, SIMD_LOG2N[fmt]-1, 0 ); - simdUnpack( a, a_values, fmt, sign ); + sa = bits(sa, SIMD_LOG2N[fmt] - 1, 0); + simdUnpack(a, a_values, fmt, sign); - for( i=0; i> sa; - simdPack( a_values, &result, fmt ); + simdPack(a_values, &result, fmt); - return( result ); + return result; } int32_t -MipsISA::dspShra( int32_t a, uint32_t sa, int32_t fmt, int32_t round, int32_t sign, uint32_t *dspctl ) +MipsISA::dspShra(int32_t a, uint32_t sa, int32_t fmt, int32_t round, + int32_t sign, uint32_t *dspctl) { - int i = 0; int nvals = SIMD_NVALS[fmt]; int32_t result; uint64_t a_values[SIMD_MAX_VALS]; - sa = bits( sa, SIMD_LOG2N[fmt]-1, 0 ); + sa = bits(sa, SIMD_LOG2N[fmt] - 1, 0); - simdUnpack( a, a_values, fmt, SIGNED ); + simdUnpack(a, a_values, fmt, SIGNED); - for( i=0; i> sa; + for (int i = 0; i < nvals; i++) { + if (round) + a_values[i] = addHalfLsb(a_values[i], sa) >> sa; else a_values[i] = a_values[i] >> sa; } - simdPack( a_values, &result, fmt ); + simdPack(a_values, &result, fmt); - return( result ); + return result; } int32_t -MipsISA::dspMulq( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t round, uint32_t *dspctl ) +MipsISA::dspMulq(int32_t a, int32_t b, int32_t fmt, int32_t saturate, + int32_t round, uint32_t *dspctl) { - int i = 0; int nvals = SIMD_NVALS[fmt]; int sa = SIMD_NBITS[fmt]; int32_t result; @@ -367,102 +358,104 @@ MipsISA::dspMulq( int32_t a, int32_t b, int32_t fmt, int32_t saturate, int32_t r uint64_t b_values[SIMD_MAX_VALS]; int64_t temp; - simdUnpack( a, a_values, fmt, SIGNED ); - simdUnpack( b, b_values, fmt, SIGNED ); + simdUnpack(a, a_values, fmt, SIGNED); + simdUnpack(b, b_values, fmt, SIGNED); - for( i=0; i> sa; + for (int i = 0; i < nvals; i++) { + if (round) + temp = + (int64_t)addHalfLsb(a_values[i] * b_values[i] << 1, sa) >> sa; else temp = (int64_t)(a_values[i] * b_values[i]) >> (sa - 1); - if( a_values[i] == FIXED_SMIN[fmt] && - b_values[i] == FIXED_SMIN[fmt] ) - { + if (a_values[i] == FIXED_SMIN[fmt] && b_values[i] == FIXED_SMIN[fmt]) { ouflag = 1; - if( saturate ) + if (saturate) temp = FIXED_SMAX[fmt]; } a_values[i] = temp; } - simdPack( a_values, &result, fmt ); + simdPack(a_values, &result, fmt); - if( ouflag ) - writeDSPControl( dspctl, (ouflag<<5)<-1; i-- ) - { + for (int i = nvals - 1; i > -1; i--) { temp[i] = a_values[i] * b_values[i] << 1; - if( a_values[i] == FIXED_SMIN[fmt] && - b_values[i] == FIXED_SMIN[fmt] ) - { - temp[i] = FIXED_SMAX[fmt-1]; + if (a_values[i] == FIXED_SMIN[fmt] && b_values[i] == FIXED_SMIN[fmt]) { + temp[i] = FIXED_SMAX[fmt - 1]; ouflag = 1; } } dspac += temp[1] - temp[0]; - if( ouflag ) - *dspctl = insertBits( *dspctl, 16+ac, 16+ac, 1 ); + if (ouflag) + *dspctl = insertBits(*dspctl, 16 + ac, 16 + ac, 1); return dspac; } void -MipsISA::dspCmp( int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op, uint32_t *dspctl ) +MipsISA::dspCmp(int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op, + uint32_t *dspctl) { - int i = 0; int nvals = SIMD_NVALS[fmt]; int ccond = 0; uint64_t a_values[SIMD_MAX_VALS]; uint64_t b_values[SIMD_MAX_VALS]; - simdUnpack( a, a_values, fmt, sign ); - simdUnpack( b, b_values, fmt, sign ); + simdUnpack(a, a_values, fmt, sign); + simdUnpack(b, b_values, fmt, sign); - for( i=0; i>1)] << sa; break; - case MODE_R: out_values[i] = in_values[i] << sa; break; - case MODE_LA: out_values[i] = in_values[(i<<1)+1] << sa; break; - case MODE_RA: out_values[i] = in_values[i<<1] << sa; break; + for (int i = 0; i> 1)] << sa; + break; + case MODE_R: + out_values[i] = in_values[i] << sa; + break; + case MODE_LA: + out_values[i] = in_values[(i << 1) + 1] << sa; + break; + case MODE_RA: + out_values[i] = in_values[i << 1] << sa; + break; } } - simdPack( out_values, &result, outfmt ); + simdPack(out_values, &result, outfmt); - return( result ); + return result; } int32_t -MipsISA::dspPrecrqu( int32_t a, int32_t b, uint32_t *dspctl ) +MipsISA::dspPrecrqu(int32_t a, int32_t b, uint32_t *dspctl) { - int i = 0; uint64_t a_values[SIMD_MAX_VALS]; uint64_t b_values[SIMD_MAX_VALS]; uint64_t r_values[SIMD_MAX_VALS]; uint32_t ouflag = 0; int32_t result = 0; - simdUnpack( a, a_values, SIMD_FMT_PH, SIGNED ); - simdUnpack( b, b_values, SIMD_FMT_PH, SIGNED ); + simdUnpack(a, a_values, SIMD_FMT_PH, SIGNED); + simdUnpack(b, b_values, SIMD_FMT_PH, SIGNED); - for( i=0; i<2; i++ ) - { - r_values[i] = dspSaturate( (int64_t)b_values[i] >> SIMD_NBITS[SIMD_FMT_QB] - 1, - SIMD_FMT_QB, UNSIGNED, &ouflag ); - r_values[i+2] = dspSaturate( (int64_t)a_values[i] >> SIMD_NBITS[SIMD_FMT_QB] - 1, - SIMD_FMT_QB, UNSIGNED, &ouflag ); + for (int i = 0; i<2; i++) { + r_values[i] = + dspSaturate((int64_t)b_values[i] >> SIMD_NBITS[SIMD_FMT_QB] - 1, + SIMD_FMT_QB, UNSIGNED, &ouflag); + r_values[i + 2] = + dspSaturate((int64_t)a_values[i] >> SIMD_NBITS[SIMD_FMT_QB] - 1, + SIMD_FMT_QB, UNSIGNED, &ouflag); } - simdPack( r_values, &result, SIMD_FMT_QB ); + simdPack(r_values, &result, SIMD_FMT_QB); - if( ouflag ) - *dspctl = insertBits( *dspctl, 22, 22, 1 ); + if (ouflag) + *dspctl = insertBits(*dspctl, 22, 22, 1); return result; } int32_t -MipsISA::dspPrecrq( int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl ) +MipsISA::dspPrecrq(int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl) { uint64_t a_values[SIMD_MAX_VALS]; uint64_t b_values[SIMD_MAX_VALS]; @@ -965,245 +947,226 @@ MipsISA::dspPrecrq( int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl ) uint32_t ouflag = 0; int32_t result; - simdUnpack( a, a_values, fmt, SIGNED ); - simdUnpack( b, b_values, fmt, SIGNED ); + simdUnpack(a, a_values, fmt, SIGNED); + simdUnpack(b, b_values, fmt, SIGNED); - r_values[1] = dspSaturate( (int64_t)addHalfLsb( a_values[0], 16 ) >> 16, - fmt+1, SIGNED, &ouflag ); - r_values[0] = dspSaturate( (int64_t)addHalfLsb( b_values[0], 16 ) >> 16, - fmt+1, SIGNED, &ouflag ); + r_values[1] = dspSaturate((int64_t)addHalfLsb(a_values[0], 16) >> 16, + fmt + 1, SIGNED, &ouflag); + r_values[0] = dspSaturate((int64_t)addHalfLsb(b_values[0], 16) >> 16, + fmt + 1, SIGNED, &ouflag); - simdPack( r_values, &result, fmt+1 ); + simdPack(r_values, &result, fmt + 1); - if( ouflag ) - *dspctl = insertBits( *dspctl, 22, 22, 1 ); + if (ouflag) + *dspctl = insertBits(*dspctl, 22, 22, 1); return result; } int32_t -MipsISA::dspPrecrSra( int32_t a, int32_t b, int32_t sa, int32_t fmt, int32_t round ) +MipsISA::dspPrecrSra(int32_t a, int32_t b, int32_t sa, int32_t fmt, + int32_t round) { - int i = 0; int nvals = SIMD_NVALS[fmt]; uint64_t a_values[SIMD_MAX_VALS]; uint64_t b_values[SIMD_MAX_VALS]; uint64_t c_values[SIMD_MAX_VALS]; int32_t result = 0; - simdUnpack( a, a_values, fmt, SIGNED ); - simdUnpack( b, b_values, fmt, SIGNED ); + simdUnpack(a, a_values, fmt, SIGNED); + simdUnpack(b, b_values, fmt, SIGNED); - for( i=0; i> sa; - c_values[i+1] = addHalfLsb( a_values[i], sa ) >> sa; - } - else - { + for (int i = 0; i < nvals; i++) { + if (round) { + c_values[i] = addHalfLsb(b_values[i], sa) >> sa; + c_values[i + 1] = addHalfLsb(a_values[i], sa) >> sa; + } else { c_values[i] = b_values[i] >> sa; - c_values[i+1] = a_values[i] >> sa; + c_values[i + 1] = a_values[i] >> sa; } } - simdPack( c_values, &result, fmt+1 ); + simdPack(c_values, &result, fmt + 1); return result; } int32_t -MipsISA::dspPick( int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl ) +MipsISA::dspPick(int32_t a, int32_t b, int32_t fmt, uint32_t *dspctl) { - int i = 0; int nvals = SIMD_NVALS[fmt]; int32_t result; uint64_t a_values[SIMD_MAX_VALS]; uint64_t b_values[SIMD_MAX_VALS]; uint64_t c_values[SIMD_MAX_VALS]; - simdUnpack( a, a_values, fmt, UNSIGNED ); - simdUnpack( b, b_values, fmt, UNSIGNED ); + simdUnpack(a, a_values, fmt, UNSIGNED); + simdUnpack(b, b_values, fmt, UNSIGNED); - for( i=0; i 0 ) - { - if( round ) - { - temp = (int64_t)addHalfLsb( dspac, sa ); + if (sa > 0) { + if (round) { + temp = (int64_t)addHalfLsb(dspac, sa); - if( dspac > 0 && temp < 0 ) - { + if (dspac > 0 && temp < 0) { ouflag = 1; - if( saturate ) + if (saturate) temp = FIXED_SMAX[SIMD_FMT_L]; } temp = temp >> sa; - } - else + } else { temp = dspac >> sa; - } - else + } + } else { temp = dspac; + } - dspac = checkOverflow( dspac, fmt, SIGNED, &ouflag ); + dspac = checkOverflow(dspac, fmt, SIGNED, &ouflag); - if( ouflag ) - { - *dspctl = insertBits( *dspctl, 23, 23, ouflag ); + if (ouflag) { + *dspctl = insertBits(*dspctl, 23, 23, ouflag); - if( saturate ) - result = (int32_t)dspSaturate( temp, fmt, SIGNED, &ouflag ); + if (saturate) + result = (int32_t)dspSaturate(temp, fmt, SIGNED, &ouflag); else result = (int32_t)temp; - } - else + } else { result = (int32_t)temp; + } - return( result ); + return result; } int32_t -MipsISA::dspExtp( int64_t dspac, int32_t size, uint32_t *dspctl ) +MipsISA::dspExtp(int64_t dspac, int32_t size, uint32_t *dspctl) { int32_t pos = 0; int32_t result = 0; - pos = bits( *dspctl, 5, 0 ); - size = bits( size, 4, 0 ); + pos = bits(*dspctl, 5, 0); + size = bits(size, 4, 0); - if( pos - (size+1) >= -1 ) - { - result = bits( dspac, pos, pos-size ); - *dspctl = insertBits( *dspctl, 14, 14, 0 ); - } - else - { + if (pos - (size + 1) >= -1) { + result = bits(dspac, pos, pos - size); + *dspctl = insertBits(*dspctl, 14, 14, 0); + } else { result = 0; - *dspctl = insertBits( *dspctl, 14, 14, 1 ); + *dspctl = insertBits(*dspctl, 14, 14, 1); } - return( result ); + return result; } int32_t -MipsISA::dspExtpd( int64_t dspac, int32_t size, uint32_t *dspctl ) +MipsISA::dspExtpd(int64_t dspac, int32_t size, uint32_t *dspctl) { int32_t pos = 0; int32_t result = 0; - pos = bits( *dspctl, 5, 0 ); - size = bits( size, 4, 0 ); - - if( pos - (size+1) >= -1 ) - { - result = bits( dspac, pos, pos-size ); - *dspctl = insertBits( *dspctl, 14, 14, 0 ); - if( pos - (size+1) >= 0 ) - *dspctl = insertBits( *dspctl, 5, 0, pos - (size+1) ); - else if( (pos - (size+1)) == -1 ) - *dspctl = insertBits( *dspctl, 5, 0, 63 ); - } - else - { + pos = bits(*dspctl, 5, 0); + size = bits(size, 4, 0); + + if (pos - (size + 1) >= -1) { + result = bits(dspac, pos, pos - size); + *dspctl = insertBits(*dspctl, 14, 14, 0); + if (pos - (size + 1) >= 0) + *dspctl = insertBits(*dspctl, 5, 0, pos - (size + 1)); + else if ((pos - (size + 1)) == -1) + *dspctl = insertBits(*dspctl, 5, 0, 63); + } else { result = 0; - *dspctl = insertBits( *dspctl, 14, 14, 1 ); + *dspctl = insertBits(*dspctl, 14, 14, 1); } - return( result ); + return result; } void -MipsISA::simdPack( uint64_t *values_ptr, int32_t *reg, int32_t fmt ) +MipsISA::simdPack(uint64_t *values_ptr, int32_t *reg, int32_t fmt) { - int i = 0; int nvals = SIMD_NVALS[fmt]; int nbits = SIMD_NBITS[fmt]; *reg = 0; - for( i=0; i Date: Fri, 26 Sep 2008 08:18:55 -0700 Subject: style: bring this file into M5 style, use the new pte translate function. --- src/arch/sparc/vtophys.cc | 162 ++++++++++++++++++++++++---------------------- 1 file changed, 85 insertions(+), 77 deletions(-) (limited to 'src/arch') diff --git a/src/arch/sparc/vtophys.cc b/src/arch/sparc/vtophys.cc index 9a93950d2..f23fb8304 100644 --- a/src/arch/sparc/vtophys.cc +++ b/src/arch/sparc/vtophys.cc @@ -40,85 +40,93 @@ using namespace std; -namespace SparcISA +namespace SparcISA { + +Addr +vtophys(Addr vaddr) { - Addr vtophys(Addr vaddr) - { - // In SPARC it's almost always impossible to turn a VA->PA w/o a context - // The only times we can kinda do it are if we have a SegKPM mapping - // and can find the real address in the tlb or we have a physical - // adddress already (beacuse we are looking at the hypervisor) - // Either case is rare, so we'll just panic. - - panic("vtophys() without context on SPARC largly worthless\n"); - M5_DUMMY_RETURN - } + // In SPARC it's almost always impossible to turn a VA->PA w/o a + // context The only times we can kinda do it are if we have a + // SegKPM mapping and can find the real address in the tlb or we + // have a physical adddress already (beacuse we are looking at the + // hypervisor) Either case is rare, so we'll just panic. + + panic("vtophys() without context on SPARC largly worthless\n"); + M5_DUMMY_RETURN; +} + +Addr +vtophys(ThreadContext *tc, Addr addr) +{ + // Here we have many options and are really implementing something like + // a fill handler to find the address since there isn't a multilevel + // table for us to walk around. + // + // 1. We are currently hyperpriv, return the address unmodified + // 2. The mmu is off return(ra->pa) + // 3. We are currently priv, use ctx0* tsbs to find the page + // 4. We are not priv, use ctxN0* tsbs to find the page + // For all accesses we check the tlbs first since it's possible that + // long standing pages (e.g. locked kernel mappings) won't be in the tsb + uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA); + + bool hpriv = bits(tlbdata,0,0); + //bool priv = bits(tlbdata,2,2); + bool addr_mask = bits(tlbdata,3,3); + bool data_real = !bits(tlbdata,5,5); + bool inst_real = !bits(tlbdata,4,4); + bool ctx_zero = bits(tlbdata,18,16) > 0; + int part_id = bits(tlbdata,15,8); + int pri_context = bits(tlbdata,47,32); + //int sec_context = bits(tlbdata,63,48); - Addr vtophys(ThreadContext *tc, Addr addr) - { - // Here we have many options and are really implementing something like - // a fill handler to find the address since there isn't a multilevel - // table for us to walk around. - // - // 1. We are currently hyperpriv, return the address unmodified - // 2. The mmu is off return(ra->pa) - // 3. We are currently priv, use ctx0* tsbs to find the page - // 4. We are not priv, use ctxN0* tsbs to find the page - // For all accesses we check the tlbs first since it's possible that - // long standing pages (e.g. locked kernel mappings) won't be in the tsb - uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA); - - bool hpriv = bits(tlbdata,0,0); - //bool priv = bits(tlbdata,2,2); - bool addr_mask = bits(tlbdata,3,3); - bool data_real = !bits(tlbdata,5,5); - bool inst_real = !bits(tlbdata,4,4); - bool ctx_zero = bits(tlbdata,18,16) > 0; - int part_id = bits(tlbdata,15,8); - int pri_context = bits(tlbdata,47,32); - //int sec_context = bits(tlbdata,63,48); - - FunctionalPort *mem = tc->getPhysPort(); - ITB* itb = tc->getITBPtr(); - DTB* dtb = tc->getDTBPtr(); - TlbEntry* tbe; - PageTableEntry pte; - Addr tsbs[4]; - Addr va_tag; - TteTag ttetag; - - if (hpriv) - return addr; - - if (addr_mask) - addr = addr & VAddrAMask; - - tbe = dtb->lookup(addr, part_id, data_real, ctx_zero ? 0 : pri_context , false); - if (tbe) goto foundtbe; - - tbe = itb->lookup(addr, part_id, inst_real, ctx_zero ? 0 : pri_context, false); - if (tbe) goto foundtbe; - - // We didn't find it in the tlbs, so lets look at the TSBs - dtb->GetTsbPtr(tc, addr, ctx_zero ? 0 : pri_context, tsbs); - va_tag = bits(addr, 63, 22); - for (int x = 0; x < 4; x++) { - ttetag = betoh(mem->read(tsbs[x])); - if (ttetag.valid() && ttetag.va() == va_tag) { - pte.populate(betoh(mem->read(tsbs[x]) + sizeof(uint64_t)), - PageTableEntry::sun4v); // I think it's sun4v at least! - DPRINTF(VtoPhys, "Virtual(%#x)->Physical(%#x) found in TTE\n", addr, - pte.paddrMask() | addr & pte.sizeMask()); - goto foundpte; - } + FunctionalPort *mem = tc->getPhysPort(); + ITB* itb = tc->getITBPtr(); + DTB* dtb = tc->getDTBPtr(); + TlbEntry* tbe; + PageTableEntry pte; + Addr tsbs[4]; + Addr va_tag; + TteTag ttetag; + + if (hpriv) + return addr; + + if (addr_mask) + addr = addr & VAddrAMask; + + tbe = dtb->lookup(addr, part_id, data_real, ctx_zero ? 0 : pri_context , + false); + if (tbe) + goto foundtbe; + + tbe = itb->lookup(addr, part_id, inst_real, ctx_zero ? 0 : pri_context, + false); + if (tbe) + goto foundtbe; + + // We didn't find it in the tlbs, so lets look at the TSBs + dtb->GetTsbPtr(tc, addr, ctx_zero ? 0 : pri_context, tsbs); + va_tag = bits(addr, 63, 22); + for (int x = 0; x < 4; x++) { + ttetag = betoh(mem->read(tsbs[x])); + if (ttetag.valid() && ttetag.va() == va_tag) { + uint64_t entry = mem->read(tsbs[x]) + sizeof(uint64_t); + // I think it's sun4v at least! + pte.populate(betoh(entry), PageTableEntry::sun4v); + DPRINTF(VtoPhys, "Virtual(%#x)->Physical(%#x) found in TTE\n", + addr, pte.translate(addr)); + goto foundpte; } - panic("couldn't translate %#x\n", addr); - -foundtbe: - pte = tbe->pte; - DPRINTF(VtoPhys, "Virtual(%#x)->Physical(%#x) found in TLB\n", addr, - pte.paddrMask() | addr & pte.sizeMask()); -foundpte: - return pte.paddrMask() | addr & pte.sizeMask(); } + panic("couldn't translate %#x\n", addr); + + foundtbe: + pte = tbe->pte; + DPRINTF(VtoPhys, "Virtual(%#x)->Physical(%#x) found in TLB\n", addr, + pte.translate(addr)); + foundpte: + return pte.translate(addr); } + +} /* namespace SparcISA */ -- cgit v1.2.3 From abca171e244b27d1c44a9bcdedbe231bdc342cbb Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 26 Sep 2008 08:18:56 -0700 Subject: Use logical operator instead of bitwise operator for correctness. --- src/arch/mips/mt.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/mips/mt.hh b/src/arch/mips/mt.hh index 6765c27a9..20658df28 100755 --- a/src/arch/mips/mt.hh +++ b/src/arch/mips/mt.hh @@ -220,7 +220,7 @@ yieldThread(TC *tc, Fault &fault, int src_reg, uint32_t yield_mask) warn("%i: Deactivating Hardware Thread Context #%i", curTick, tc->getThreadNum()); } } else if (src_reg > 0) { - if (src_reg & !yield_mask != 0) { + if (src_reg && !yield_mask != 0) { unsigned vpe_control = tc->readMiscReg(VPEControl); tc->setMiscReg(VPEControl, insertBits(vpe_control, VPEC_EXCPT_HI, VPEC_EXCPT_LO, 2)); fault = new ThreadFault(); -- cgit v1.2.3 From 9838be252114cf044735ca07007d23ee03d8da2c Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 26 Sep 2008 08:18:57 -0700 Subject: When nesting if statements, use braces to avoid ambiguous else clauses. --- src/arch/sparc/tlb_map.hh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/sparc/tlb_map.hh b/src/arch/sparc/tlb_map.hh index 8285db939..fa49584ba 100644 --- a/src/arch/sparc/tlb_map.hh +++ b/src/arch/sparc/tlb_map.hh @@ -52,7 +52,7 @@ class TlbMap i = tree.upper_bound(r); - if (i == tree.begin()) + if (i == tree.begin()) { if (r.real == i->first.real && r.partitionId == i->first.partitionId && i->first.va < r.va + r.size && @@ -62,6 +62,7 @@ class TlbMap else // Nothing could match, so return end() return tree.end(); + } i--; -- cgit v1.2.3 From ca4baf387134f75b5e78a22c4c18d63fb5f48201 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 26 Sep 2008 09:37:21 -0700 Subject: style: missed space after switch --- src/arch/mips/dsp.cc | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'src/arch') diff --git a/src/arch/mips/dsp.cc b/src/arch/mips/dsp.cc index 183016ee7..fc3ae65d6 100755 --- a/src/arch/mips/dsp.cc +++ b/src/arch/mips/dsp.cc @@ -63,7 +63,7 @@ MipsISA::dspSaturate(uint64_t value, int32_t fmt, int32_t sign, { int64_t svalue = (int64_t)value; - switch(sign) { + switch (sign) { case SIGNED: if (svalue > (int64_t)FIXED_SMAX[fmt]) { *overflow = 1; @@ -93,7 +93,7 @@ MipsISA::checkOverflow(uint64_t value, int32_t fmt, int32_t sign, { int64_t svalue = (int64_t)value; - switch(sign) + switch (sign) { case SIGNED: if (svalue > (int64_t)FIXED_SMAX[fmt] || @@ -431,7 +431,7 @@ MipsISA::dspMuleu(int32_t a, int32_t b, int32_t mode, uint32_t *dspctl) simdUnpack(a, a_values, SIMD_FMT_QB, UNSIGNED); simdUnpack(b, b_values, SIMD_FMT_PH, UNSIGNED); - switch(mode) { + switch (mode) { case MODE_L: for (int i = 0; i < nvals; i++) b_values[i] = dspSaturate(a_values[i + 2] * b_values[i], @@ -466,7 +466,7 @@ MipsISA::dspMuleq(int32_t a, int32_t b, int32_t mode, uint32_t *dspctl) simdUnpack(a, a_values, SIMD_FMT_PH, SIGNED); simdUnpack(b, b_values, SIMD_FMT_PH, SIGNED); - switch(mode) { + switch (mode) { case MODE_L: for (int i = 0; i < nvals; i++) c_values[i] = dspSaturate(a_values[i + 1] * b_values[i + 1] << 1, @@ -504,7 +504,7 @@ MipsISA::dspDpaq(int64_t dspac, int32_t a, int32_t b, int32_t ac, simdUnpack(b, b_values, infmt, SIGNED); for (int i = 0; i < nvals; i++) { - switch(mode) { + switch (mode) { case MODE_X: if (a_values[nvals - 1 - i] == FIXED_SMIN[infmt] && b_values[i] == FIXED_SMIN[infmt]) { @@ -571,7 +571,7 @@ MipsISA::dspDpsq(int64_t dspac, int32_t a, int32_t b, int32_t ac, simdUnpack(b, b_values, infmt, SIGNED); for (int i = 0; i < nvals; i++) { - switch(mode) { + switch (mode) { case MODE_X: if (a_values[nvals - 1 - i] == FIXED_SMIN[infmt] && b_values[i] == FIXED_SMIN[infmt]) { @@ -634,7 +634,7 @@ MipsISA::dspDpa(int64_t dspac, int32_t a, int32_t b, int32_t ac, simdUnpack(b, b_values, fmt, sign); for (int i = 0; i < 2; i++) { - switch(mode) { + switch (mode) { case MODE_L: dspac += a_values[nvals - 1 - i] * b_values[nvals - 1 - i]; break; @@ -662,7 +662,7 @@ MipsISA::dspDps(int64_t dspac, int32_t a, int32_t b, int32_t ac, simdUnpack(b, b_values, fmt, sign); for (int i = 0; i < 2; i++) { - switch(mode) { + switch (mode) { case MODE_L: dspac -= a_values[nvals - 1 - i] * b_values[nvals - 1 - i]; break; @@ -692,7 +692,7 @@ MipsISA::dspMaq(int64_t dspac, int32_t a, int32_t b, int32_t ac, simdUnpack(b, b_values, fmt, SIGNED); for (int i = 0; i < nvals; i++) { - switch(mode) { + switch (mode) { case MODE_L: temp = a_values[i + 1] * b_values[i + 1] << 1; if (a_values[i + 1] == FIXED_SMIN[fmt] && @@ -780,7 +780,7 @@ MipsISA::dspCmp(int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op, for (int i = 0; i < nvals; i++) { int cc = 0; - switch(op) { + switch (op) { case CMP_EQ: cc = (a_values[i] == b_values[i]); break; @@ -812,7 +812,7 @@ MipsISA::dspCmpg(int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op) for (int i = 0; i < nvals; i++) { int cc = 0; - switch(op) { + switch (op) { case CMP_EQ: cc = (a_values[i] == b_values[i]); break; @@ -846,7 +846,7 @@ MipsISA::dspCmpgd(int32_t a, int32_t b, int32_t fmt, int32_t sign, int32_t op, for (int i = 0; i < nvals; i++) { int cc = 0; - switch(op) { + switch (op) { case CMP_EQ: cc = (a_values[i] == b_values[i]); break; @@ -888,7 +888,7 @@ MipsISA::dspPrece(int32_t a, int32_t infmt, int32_t insign, int32_t outfmt, simdUnpack(a, in_values, infmt, insign); for (int i = 0; i> 1)] << sa; break; @@ -1140,7 +1140,7 @@ MipsISA::simdUnpack(int32_t reg, uint64_t *values_ptr, int32_t fmt, int32_t sign int nvals = SIMD_NVALS[fmt]; int nbits = SIMD_NBITS[fmt]; - switch(sign) { + switch (sign) { case SIGNED: for (int i = 0; i < nvals; i++) { uint64_t tmp = (uint64_t)bits(reg, nbits * (i + 1) - 1, nbits * i); -- cgit v1.2.3 From 819023b8e2be98479a391cec1b24dbe159479737 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 27 Sep 2008 07:25:04 -0700 Subject: style --- src/arch/alpha/interrupts.hh | 228 ++++++++++++++++++++++--------------------- 1 file changed, 119 insertions(+), 109 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/interrupts.hh b/src/arch/alpha/interrupts.hh index 6453edf97..009b41637 100644 --- a/src/arch/alpha/interrupts.hh +++ b/src/arch/alpha/interrupts.hh @@ -37,140 +37,150 @@ #include "base/compiler.hh" #include "cpu/thread_context.hh" -namespace AlphaISA +namespace AlphaISA { + +class Interrupts { - class Interrupts + private: + bool newInfoSet; + int newIpl; + int newSummary; + + protected: + uint64_t interrupts[NumInterruptLevels]; + uint64_t intstatus; + + public: + Interrupts() { - protected: - uint64_t interrupts[NumInterruptLevels]; - uint64_t intstatus; - - public: - Interrupts() - { - memset(interrupts, 0, sizeof(interrupts)); - intstatus = 0; - newInfoSet = false; - } + memset(interrupts, 0, sizeof(interrupts)); + intstatus = 0; + newInfoSet = false; + } - void post(int int_num, int index) - { - DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); + void + post(int int_num, int index) + { + DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); - if (int_num < 0 || int_num >= NumInterruptLevels) - panic("int_num out of bounds\n"); + if (int_num < 0 || int_num >= NumInterruptLevels) + panic("int_num out of bounds\n"); - if (index < 0 || index >= sizeof(uint64_t) * 8) - panic("int_num out of bounds\n"); + if (index < 0 || index >= (int)sizeof(uint64_t) * 8) + panic("int_num out of bounds\n"); - interrupts[int_num] |= 1 << index; - intstatus |= (ULL(1) << int_num); - } + interrupts[int_num] |= 1 << index; + intstatus |= (ULL(1) << int_num); + } - void clear(int int_num, int index) - { - DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); + void + clear(int int_num, int index) + { + DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); - if (int_num < 0 || int_num >= TheISA::NumInterruptLevels) - panic("int_num out of bounds\n"); + if (int_num < 0 || int_num >= TheISA::NumInterruptLevels) + panic("int_num out of bounds\n"); - if (index < 0 || index >= sizeof(uint64_t) * 8) - panic("int_num out of bounds\n"); + if (index < 0 || index >= (int)sizeof(uint64_t) * 8) + panic("int_num out of bounds\n"); - interrupts[int_num] &= ~(1 << index); - if (interrupts[int_num] == 0) - intstatus &= ~(ULL(1) << int_num); - } + interrupts[int_num] &= ~(1 << index); + if (interrupts[int_num] == 0) + intstatus &= ~(ULL(1) << int_num); + } - void clear_all() - { - DPRINTF(Interrupt, "Interrupts all cleared\n"); + void + clear_all() + { + DPRINTF(Interrupt, "Interrupts all cleared\n"); - memset(interrupts, 0, sizeof(interrupts)); - intstatus = 0; - } + memset(interrupts, 0, sizeof(interrupts)); + intstatus = 0; + } - void serialize(std::ostream &os) - { - SERIALIZE_ARRAY(interrupts, NumInterruptLevels); - SERIALIZE_SCALAR(intstatus); - } + void + serialize(std::ostream &os) + { + SERIALIZE_ARRAY(interrupts, NumInterruptLevels); + SERIALIZE_SCALAR(intstatus); + } - void unserialize(Checkpoint *cp, const std::string §ion) - { - UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels); - UNSERIALIZE_SCALAR(intstatus); - } + void + unserialize(Checkpoint *cp, const std::string §ion) + { + UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels); + UNSERIALIZE_SCALAR(intstatus); + } - bool check_interrupts(ThreadContext * tc) const - { - return (intstatus != 0) && !(tc->readPC() & 0x3); - } + bool + check_interrupts(ThreadContext *tc) const + { + return (intstatus != 0) && !(tc->readPC() & 0x3); + } - Fault getInterrupt(ThreadContext * tc) - { - int ipl = 0; - int summary = 0; - - if (tc->readMiscRegNoEffect(IPR_ASTRR)) - panic("asynchronous traps not implemented\n"); - - if (tc->readMiscRegNoEffect(IPR_SIRR)) { - for (int i = INTLEVEL_SOFTWARE_MIN; - i < INTLEVEL_SOFTWARE_MAX; i++) { - if (tc->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) { - // See table 4-19 of 21164 hardware reference - ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; - summary |= (ULL(1) << i); - } + Fault + getInterrupt(ThreadContext *tc) + { + int ipl = 0; + int summary = 0; + + if (tc->readMiscRegNoEffect(IPR_ASTRR)) + panic("asynchronous traps not implemented\n"); + + if (tc->readMiscRegNoEffect(IPR_SIRR)) { + for (int i = INTLEVEL_SOFTWARE_MIN; + i < INTLEVEL_SOFTWARE_MAX; i++) { + if (tc->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) { + // See table 4-19 of 21164 hardware reference + ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; + summary |= (ULL(1) << i); } } + } - uint64_t interrupts = intstatus; - if (interrupts) { - for (int i = INTLEVEL_EXTERNAL_MIN; - i < INTLEVEL_EXTERNAL_MAX; i++) { - if (interrupts & (ULL(1) << i)) { - // See table 4-19 of 21164 hardware reference - ipl = i; - summary |= (ULL(1) << i); - } + uint64_t interrupts = intstatus; + if (interrupts) { + for (int i = INTLEVEL_EXTERNAL_MIN; + i < INTLEVEL_EXTERNAL_MAX; i++) { + if (interrupts & (ULL(1) << i)) { + // See table 4-19 of 21164 hardware reference + ipl = i; + summary |= (ULL(1) << i); } } - - if (ipl && ipl > tc->readMiscRegNoEffect(IPR_IPLR)) { - newIpl = ipl; - newSummary = summary; - newInfoSet = true; - DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", - tc->readMiscRegNoEffect(IPR_IPLR), ipl, summary); - - return new InterruptFault; - } else { - return NoFault; - } } - void updateIntrInfo(ThreadContext *tc) - { - assert(newInfoSet); - tc->setMiscRegNoEffect(IPR_ISR, newSummary); - tc->setMiscRegNoEffect(IPR_INTID, newIpl); - newInfoSet = false; - } + if (ipl && ipl > tc->readMiscRegNoEffect(IPR_IPLR)) { + newIpl = ipl; + newSummary = summary; + newInfoSet = true; + DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", + tc->readMiscRegNoEffect(IPR_IPLR), ipl, summary); - uint64_t get_vec(int int_num) - { - panic("Shouldn't be called for Alpha\n"); - M5_DUMMY_RETURN + return new InterruptFault; + } else { + return NoFault; } + } + + void + updateIntrInfo(ThreadContext *tc) + { + assert(newInfoSet); + tc->setMiscRegNoEffect(IPR_ISR, newSummary); + tc->setMiscRegNoEffect(IPR_INTID, newIpl); + newInfoSet = false; + } + + uint64_t + get_vec(int int_num) + { + panic("Shouldn't be called for Alpha\n"); + M5_DUMMY_RETURN; + } +}; - private: - bool newInfoSet; - int newIpl; - int newSummary; - }; -} +} // namespace AlphaISA -#endif +#endif // __ARCH_ALPHA_INTERRUPT_HH__ -- cgit v1.2.3 From 0b30c345f17f928c99660d633147f24f4f0035bd Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 27 Sep 2008 21:03:45 -0700 Subject: alpha: Get rid fo the namespace called EV5. We're never going to do an alpha platform other than the one we've got. --- src/arch/alpha/ev5.cc | 44 ++++++++++++++++++------------------- src/arch/alpha/ev5.hh | 7 ++---- src/arch/alpha/faults.cc | 4 ++-- src/arch/alpha/isa/fp.isa | 2 +- src/arch/alpha/system.cc | 2 +- src/arch/alpha/tlb.cc | 1 - src/arch/alpha/tlb.hh | 4 ++-- src/arch/alpha/vtophys.cc | 2 +- src/arch/mips/mips_core_specific.cc | 4 ++-- src/arch/mips/system.cc | 2 +- 10 files changed, 34 insertions(+), 38 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index 33306d6af..83900349e 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -44,9 +44,9 @@ #include "sim/debug.hh" #include "sim/sim_exit.hh" -#if FULL_SYSTEM +using namespace AlphaISA; -using namespace EV5; +#if FULL_SYSTEM //////////////////////////////////////////////////////////////////////// // @@ -146,13 +146,13 @@ SimpleThread::hwrei() int AlphaISA::MiscRegFile::getInstAsid() { - return EV5::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); + return AlphaISA::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); } int AlphaISA::MiscRegFile::getDataAsid() { - return EV5::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); + return AlphaISA::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); } #endif @@ -168,7 +168,7 @@ AlphaISA::initIPRs(ThreadContext *tc, int cpuId) tc->setMiscRegNoEffect(i, 0); } - tc->setMiscRegNoEffect(IPR_PAL_BASE, EV5::PalBase); + tc->setMiscRegNoEffect(IPR_PAL_BASE, AlphaISA::PalBase); tc->setMiscRegNoEffect(IPR_MCSR, 0x6); tc->setMiscRegNoEffect(IPR_PALtemp16, cpuId); } @@ -477,27 +477,27 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) ipr[idx] = val; tc->getDTBPtr()->flushAddr(val, - EV5::DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); + AlphaISA::DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); break; case AlphaISA::IPR_DTB_TAG: { struct AlphaISA::TlbEntry entry; // FIXME: granularity hints NYI... - if (EV5::DTB_PTE_GH(ipr[AlphaISA::IPR_DTB_PTE]) != 0) + if (AlphaISA::DTB_PTE_GH(ipr[AlphaISA::IPR_DTB_PTE]) != 0) panic("PTE GH field != 0"); // write entire quad ipr[idx] = val; // construct PTE for new entry - entry.ppn = EV5::DTB_PTE_PPN(ipr[AlphaISA::IPR_DTB_PTE]); - entry.xre = EV5::DTB_PTE_XRE(ipr[AlphaISA::IPR_DTB_PTE]); - entry.xwe = EV5::DTB_PTE_XWE(ipr[AlphaISA::IPR_DTB_PTE]); - entry.fonr = EV5::DTB_PTE_FONR(ipr[AlphaISA::IPR_DTB_PTE]); - entry.fonw = EV5::DTB_PTE_FONW(ipr[AlphaISA::IPR_DTB_PTE]); - entry.asma = EV5::DTB_PTE_ASMA(ipr[AlphaISA::IPR_DTB_PTE]); - entry.asn = EV5::DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]); + entry.ppn = AlphaISA::DTB_PTE_PPN(ipr[AlphaISA::IPR_DTB_PTE]); + entry.xre = AlphaISA::DTB_PTE_XRE(ipr[AlphaISA::IPR_DTB_PTE]); + entry.xwe = AlphaISA::DTB_PTE_XWE(ipr[AlphaISA::IPR_DTB_PTE]); + entry.fonr = AlphaISA::DTB_PTE_FONR(ipr[AlphaISA::IPR_DTB_PTE]); + entry.fonw = AlphaISA::DTB_PTE_FONW(ipr[AlphaISA::IPR_DTB_PTE]); + entry.asma = AlphaISA::DTB_PTE_ASMA(ipr[AlphaISA::IPR_DTB_PTE]); + entry.asn = AlphaISA::DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]); // insert new TAG/PTE value into data TLB tc->getDTBPtr()->insert(val, entry); @@ -508,20 +508,20 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) struct AlphaISA::TlbEntry entry; // FIXME: granularity hints NYI... - if (EV5::ITB_PTE_GH(val) != 0) + if (AlphaISA::ITB_PTE_GH(val) != 0) panic("PTE GH field != 0"); // write entire quad ipr[idx] = val; // construct PTE for new entry - entry.ppn = EV5::ITB_PTE_PPN(val); - entry.xre = EV5::ITB_PTE_XRE(val); + entry.ppn = AlphaISA::ITB_PTE_PPN(val); + entry.xre = AlphaISA::ITB_PTE_XRE(val); entry.xwe = 0; - entry.fonr = EV5::ITB_PTE_FONR(val); - entry.fonw = EV5::ITB_PTE_FONW(val); - entry.asma = EV5::ITB_PTE_ASMA(val); - entry.asn = EV5::ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]); + entry.fonr = AlphaISA::ITB_PTE_FONR(val); + entry.fonw = AlphaISA::ITB_PTE_FONW(val); + entry.asma = AlphaISA::ITB_PTE_ASMA(val); + entry.asn = AlphaISA::ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]); // insert new TAG/PTE value into data TLB tc->getITBPtr()->insert(ipr[AlphaISA::IPR_ITB_TAG], entry); @@ -547,7 +547,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) ipr[idx] = val; tc->getITBPtr()->flushAddr(val, - EV5::ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN])); + AlphaISA::ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN])); break; default: diff --git a/src/arch/alpha/ev5.hh b/src/arch/alpha/ev5.hh index 4dd225786..4fe5f1b71 100644 --- a/src/arch/alpha/ev5.hh +++ b/src/arch/alpha/ev5.hh @@ -36,10 +36,7 @@ #include "config/alpha_tlaser.hh" #include "arch/alpha/isa_traits.hh" -namespace EV5 { - -//It seems like a safe assumption EV5 only applies to alpha -using namespace AlphaISA; +namespace AlphaISA { #if ALPHA_TLASER const uint64_t AsnMask = ULL(0x7f); @@ -120,6 +117,6 @@ inline int Ra(AlphaISA::MachInst inst) { return inst >> 21 & 0x1f; } const Addr PalBase = 0x4000; const Addr PalMax = 0x10000; -/* namespace EV5 */ } +} // namespace AlphaISA #endif // __ARCH_ALPHA_EV5_HH__ diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc index 20591b357..7417ada5f 100644 --- a/src/arch/alpha/faults.cc +++ b/src/arch/alpha/faults.cc @@ -148,8 +148,8 @@ void DtbFault::invoke(ThreadContext * tc) // set MM_STAT register flags tc->setMiscRegNoEffect(AlphaISA::IPR_MM_STAT, - (((EV5::Opcode(tc->getInst()) & 0x3f) << 11) - | ((EV5::Ra(tc->getInst()) & 0x1f) << 6) + (((AlphaISA::Opcode(tc->getInst()) & 0x3f) << 11) + | ((AlphaISA::Ra(tc->getInst()) & 0x1f) << 6) | (flags & 0x3f))); // set VA_FORM register with faulting formatted address diff --git a/src/arch/alpha/isa/fp.isa b/src/arch/alpha/isa/fp.isa index 773e7d10c..8b13f8dd7 100644 --- a/src/arch/alpha/isa/fp.isa +++ b/src/arch/alpha/isa/fp.isa @@ -46,7 +46,7 @@ output exec {{ inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) { Fault fault = NoFault; // dummy... this ipr access should not fault - if (!EV5::ICSR_FPE(xc->readMiscReg(AlphaISA::IPR_ICSR))) { + if (!AlphaISA::ICSR_FPE(xc->readMiscReg(AlphaISA::IPR_ICSR))) { fault = new FloatEnableFault; } return fault; diff --git a/src/arch/alpha/system.cc b/src/arch/alpha/system.cc index f8fea4fee..63efef4a0 100644 --- a/src/arch/alpha/system.cc +++ b/src/arch/alpha/system.cc @@ -190,7 +190,7 @@ AlphaSystem::setAlphaAccess(Addr access) { Addr addr = 0; if (consoleSymtab->findAddress("m5AlphaAccess", addr)) { - virtPort.write(addr, htog(EV5::Phys2K0Seg(access))); + virtPort.write(addr, htog(AlphaISA::Phys2K0Seg(access))); } else panic("could not find m5AlphaAccess\n"); } diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc index 60502ebdb..2694cf38f 100644 --- a/src/arch/alpha/tlb.cc +++ b/src/arch/alpha/tlb.cc @@ -43,7 +43,6 @@ #include "cpu/thread_context.hh" using namespace std; -using namespace EV5; namespace AlphaISA { /////////////////////////////////////////////////////////////////////// diff --git a/src/arch/alpha/tlb.hh b/src/arch/alpha/tlb.hh index f94d06ccd..98f845e21 100644 --- a/src/arch/alpha/tlb.hh +++ b/src/arch/alpha/tlb.hh @@ -88,8 +88,8 @@ namespace AlphaISA // static helper functions... really EV5 VM traits static bool validVirtualAddress(Addr vaddr) { // unimplemented bits must be all 0 or all 1 - Addr unimplBits = vaddr & EV5::VAddrUnImplMask; - return (unimplBits == 0) || (unimplBits == EV5::VAddrUnImplMask); + Addr unimplBits = vaddr & AlphaISA::VAddrUnImplMask; + return (unimplBits == 0) || (unimplBits == AlphaISA::VAddrUnImplMask); } static Fault checkCacheability(RequestPtr &req, bool itb = false); diff --git a/src/arch/alpha/vtophys.cc b/src/arch/alpha/vtophys.cc index 6ffbea181..439af3bd7 100644 --- a/src/arch/alpha/vtophys.cc +++ b/src/arch/alpha/vtophys.cc @@ -92,7 +92,7 @@ AlphaISA::vtophys(ThreadContext *tc, Addr addr) Addr paddr = 0; //@todo Andrew couldn't remember why he commented some of this code //so I put it back in. Perhaps something to do with gdb debugging? - if (AlphaISA::PcPAL(vaddr) && (vaddr < EV5::PalMax)) { + if (AlphaISA::PcPAL(vaddr) && (vaddr < AlphaISA::PalMax)) { paddr = vaddr & ~ULL(1); } else { if (AlphaISA::IsK0Seg(vaddr)) { diff --git a/src/arch/mips/mips_core_specific.cc b/src/arch/mips/mips_core_specific.cc index a17ebcdf3..80d856b0c 100755 --- a/src/arch/mips/mips_core_specific.cc +++ b/src/arch/mips/mips_core_specific.cc @@ -113,13 +113,13 @@ MipsISA::processInterrupts(CPU *cpu) /*int MipsISA::MiscRegFile::getInstAsid() { - return EV5::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); + return AlphaISA::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); } int MipsISA::MiscRegFile::getDataAsid() { - return EV5::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); + return AlphaISA::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); }*/ diff --git a/src/arch/mips/system.cc b/src/arch/mips/system.cc index bf86bb030..73bc33161 100755 --- a/src/arch/mips/system.cc +++ b/src/arch/mips/system.cc @@ -185,7 +185,7 @@ MipsSystem::setMipsAccess(Addr access) { Addr addr = 0; if (consoleSymtab->findAddress("m5MipsAccess", addr)) { - // virtPort.write(addr, htog(EV5::Phys2K0Seg(access))); + // virtPort.write(addr, htog(AlphaISA::Phys2K0Seg(access))); } else panic("could not find m5MipsAccess\n"); } -- cgit v1.2.3 From 8ea5176b7f4eac09d152dd63d0ba07962be9c865 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 27 Sep 2008 21:03:46 -0700 Subject: arch: TheISA shouldn't really ever be used in the arch directory. We should always refer to the specific ISA in that arch directory. This is especially necessary if we're ever going to make it to the point where we actually have heterogeneous systems. --- src/arch/alpha/ev5.cc | 4 ++-- src/arch/alpha/idle_event.cc | 2 +- src/arch/alpha/interrupts.hh | 2 +- src/arch/alpha/linux/threadinfo.hh | 4 ++-- src/arch/alpha/regfile.cc | 2 +- src/arch/alpha/remote_gdb.cc | 26 +++++++++++++------------- src/arch/alpha/stacktrace.cc | 2 +- src/arch/alpha/stacktrace.hh | 2 +- src/arch/alpha/tru64/process.cc | 2 +- src/arch/mips/idle_event.cc | 2 +- src/arch/mips/linux/threadinfo.hh | 4 ++-- src/arch/mips/regfile/misc_regfile.cc | 2 +- src/arch/mips/stacktrace.cc | 2 +- src/arch/mips/stacktrace.hh | 2 +- src/arch/sparc/process.cc | 2 +- src/arch/sparc/regfile.cc | 4 ++-- src/arch/sparc/remote_gdb.cc | 2 +- src/arch/sparc/stacktrace.cc | 2 +- src/arch/sparc/stacktrace.hh | 2 +- src/arch/x86/process.cc | 6 +++--- src/arch/x86/remote_gdb.cc | 2 +- 21 files changed, 39 insertions(+), 39 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index 83900349e..45d2ff5a5 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -383,10 +383,10 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) #if FULL_SYSTEM if (val & 0x18) { if (tc->getKernelStats()) - tc->getKernelStats()->mode(TheISA::Kernel::user, tc); + tc->getKernelStats()->mode(AlphaISA::Kernel::user, tc); } else { if (tc->getKernelStats()) - tc->getKernelStats()->mode(TheISA::Kernel::kernel, tc); + tc->getKernelStats()->mode(AlphaISA::Kernel::kernel, tc); } #endif diff --git a/src/arch/alpha/idle_event.cc b/src/arch/alpha/idle_event.cc index f0f1eab7a..d3807a48d 100644 --- a/src/arch/alpha/idle_event.cc +++ b/src/arch/alpha/idle_event.cc @@ -33,7 +33,7 @@ #include "arch/alpha/kernel_stats.hh" #include "cpu/thread_context.hh" -using namespace TheISA; +using namespace AlphaISA; void IdleStartEvent::process(ThreadContext *tc) diff --git a/src/arch/alpha/interrupts.hh b/src/arch/alpha/interrupts.hh index 009b41637..1d8ba736f 100644 --- a/src/arch/alpha/interrupts.hh +++ b/src/arch/alpha/interrupts.hh @@ -78,7 +78,7 @@ class Interrupts { DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); - if (int_num < 0 || int_num >= TheISA::NumInterruptLevels) + if (int_num < 0 || int_num >= AlphaISA::NumInterruptLevels) panic("int_num out of bounds\n"); if (index < 0 || index >= (int)sizeof(uint64_t) * 8) diff --git a/src/arch/alpha/linux/threadinfo.hh b/src/arch/alpha/linux/threadinfo.hh index b0c8284be..3ec1aa098 100644 --- a/src/arch/alpha/linux/threadinfo.hh +++ b/src/arch/alpha/linux/threadinfo.hh @@ -55,7 +55,7 @@ class ThreadInfo CopyOut(tc, &data, addr, sizeof(T)); - data = TheISA::gtoh(data); + data = AlphaISA::gtoh(data); return true; } @@ -76,7 +76,7 @@ class ThreadInfo Addr sp; if (!addr) - addr = tc->readMiscRegNoEffect(TheISA::IPR_PALtemp23); + addr = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23); FunctionalPort *p = tc->getPhysPort(); p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr)); diff --git a/src/arch/alpha/regfile.cc b/src/arch/alpha/regfile.cc index 2653310d7..3faa189ca 100644 --- a/src/arch/alpha/regfile.cc +++ b/src/arch/alpha/regfile.cc @@ -70,7 +70,7 @@ namespace AlphaISA } // Then loop through the floating point registers. - for (int i = 0; i < TheISA::NumFloatRegs; ++i) { + for (int i = 0; i < AlphaISA::NumFloatRegs; ++i) { dest->setFloatRegBits(i, src->readFloatRegBits(i)); } diff --git a/src/arch/alpha/remote_gdb.cc b/src/arch/alpha/remote_gdb.cc index 8d70ebfa2..a40d06f18 100644 --- a/src/arch/alpha/remote_gdb.cc +++ b/src/arch/alpha/remote_gdb.cc @@ -140,7 +140,7 @@ #include "sim/system.hh" using namespace std; -using namespace TheISA; +using namespace AlphaISA; RemoteGDB::RemoteGDB(System *_system, ThreadContext *c) : BaseRemoteGDB(_system, c, KGDB_NUMREGS) @@ -161,12 +161,12 @@ RemoteGDB::acc(Addr va, size_t len) #else Addr last_va; - va = TheISA::TruncPage(va); - last_va = TheISA::RoundPage(va + len); + va = AlphaISA::TruncPage(va); + last_va = AlphaISA::RoundPage(va + len); do { - if (TheISA::IsK0Seg(va)) { - if (va < (TheISA::K0SegBase + pmem->size())) { + if (AlphaISA::IsK0Seg(va)) { + if (va < (AlphaISA::K0SegBase + pmem->size())) { DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= " "%#x < K0SEG + size\n", va); return true; @@ -188,12 +188,12 @@ RemoteGDB::acc(Addr va, size_t len) return true; Addr ptbr = context->readMiscRegNoEffect(AlphaISA::IPR_PALtemp20); - TheISA::PageTableEntry pte = TheISA::kernel_pte_lookup(context->getPhysPort(), ptbr, va); + AlphaISA::PageTableEntry pte = AlphaISA::kernel_pte_lookup(context->getPhysPort(), ptbr, va); if (!pte.valid()) { DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va); return false; } - va += TheISA::PageBytes; + va += AlphaISA::PageBytes; } while (va < last_va); DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va); @@ -215,17 +215,17 @@ RemoteGDB::getregs() // @todo: Currently this is very Alpha specific. if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) { - for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { + for (int i = 0; i < AlphaISA::NumIntArchRegs; ++i) { gdbregs.regs[i] = context->readIntReg(AlphaISA::reg_redir[i]); } } else { - for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { + for (int i = 0; i < AlphaISA::NumIntArchRegs; ++i) { gdbregs.regs[i] = context->readIntReg(i); } } #ifdef KGDB_FP_REGS - for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) { + for (int i = 0; i < AlphaISA::NumFloatArchRegs; ++i) { gdbregs.regs[i + KGDB_REG_F0] = context->readFloatRegBits(i); } #endif @@ -242,17 +242,17 @@ RemoteGDB::setregs() { // @todo: Currently this is very Alpha specific. if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) { - for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { + for (int i = 0; i < AlphaISA::NumIntArchRegs; ++i) { context->setIntReg(AlphaISA::reg_redir[i], gdbregs.regs[i]); } } else { - for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { + for (int i = 0; i < AlphaISA::NumIntArchRegs; ++i) { context->setIntReg(i, gdbregs.regs[i]); } } #ifdef KGDB_FP_REGS - for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) { + for (int i = 0; i < AlphaISA::NumFloatArchRegs; ++i) { context->setFloatRegBits(i, gdbregs.regs[i + KGDB_REG_F0]); } #endif diff --git a/src/arch/alpha/stacktrace.cc b/src/arch/alpha/stacktrace.cc index 124949781..b2fa89cb8 100644 --- a/src/arch/alpha/stacktrace.cc +++ b/src/arch/alpha/stacktrace.cc @@ -159,7 +159,7 @@ namespace AlphaISA } SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; - Addr ksp = tc->readIntReg(TheISA::StackPointerReg); + Addr ksp = tc->readIntReg(AlphaISA::StackPointerReg); Addr bottom = ksp & ~0x3fff; Addr addr; diff --git a/src/arch/alpha/stacktrace.hh b/src/arch/alpha/stacktrace.hh index 834abbc2f..c028afe2b 100644 --- a/src/arch/alpha/stacktrace.hh +++ b/src/arch/alpha/stacktrace.hh @@ -62,7 +62,7 @@ namespace AlphaISA class StackTrace { protected: - typedef TheISA::MachInst MachInst; + typedef AlphaISA::MachInst MachInst; private: ThreadContext *tc; std::vector stack; diff --git a/src/arch/alpha/tru64/process.cc b/src/arch/alpha/tru64/process.cc index 5f448489e..455a24584 100644 --- a/src/arch/alpha/tru64/process.cc +++ b/src/arch/alpha/tru64/process.cc @@ -166,7 +166,7 @@ SyscallReturn tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { using namespace std; - using namespace TheISA; + using namespace AlphaISA; int id = tc->getSyscallArg(0); // table ID int index = tc->getSyscallArg(1); // index into table diff --git a/src/arch/mips/idle_event.cc b/src/arch/mips/idle_event.cc index d1d4f7c63..0aea08834 100644 --- a/src/arch/mips/idle_event.cc +++ b/src/arch/mips/idle_event.cc @@ -34,7 +34,7 @@ #include "arch/mips/kernel_stats.hh" #include "cpu/thread_context.hh" -using namespace TheISA; +using namespace MipsISA; void IdleStartEvent::process(ThreadContext *tc) diff --git a/src/arch/mips/linux/threadinfo.hh b/src/arch/mips/linux/threadinfo.hh index 25ee74dd3..b0d0cd811 100644 --- a/src/arch/mips/linux/threadinfo.hh +++ b/src/arch/mips/linux/threadinfo.hh @@ -55,7 +55,7 @@ class ThreadInfo CopyOut(tc, &data, addr, sizeof(T)); - data = TheISA::gtoh(data); + data = MipsISA::gtoh(data); return true; } @@ -77,7 +77,7 @@ class ThreadInfo Addr sp; if (!addr) - addr = tc->readMiscRegNoEffect(0/*TheISA::IPR_PALtemp23*/); + addr = tc->readMiscRegNoEffect(0/*MipsISA::IPR_PALtemp23*/); FunctionalPort *p = tc->getPhysPort(); p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr)); diff --git a/src/arch/mips/regfile/misc_regfile.cc b/src/arch/mips/regfile/misc_regfile.cc index b82a94103..e81f940f5 100755 --- a/src/arch/mips/regfile/misc_regfile.cc +++ b/src/arch/mips/regfile/misc_regfile.cc @@ -186,7 +186,7 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads, num_threads, num_vpes); cpu = _cpu; - TheISA::CoreSpecific &cp = cpu->coreParams; + MipsISA::CoreSpecific &cp = cpu->coreParams; // Do Default CP0 initialization HERE diff --git a/src/arch/mips/stacktrace.cc b/src/arch/mips/stacktrace.cc index 482d264e8..04a9a0f18 100644 --- a/src/arch/mips/stacktrace.cc +++ b/src/arch/mips/stacktrace.cc @@ -159,7 +159,7 @@ StackTrace::trace(ThreadContext *_tc, bool is_call) // } // SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; -// Addr ksp = tc->readIntReg(TheISA::StackPointerReg); +// Addr ksp = tc->readIntReg(MipsISA::StackPointerReg); // Addr bottom = ksp & ~0x3fff; // Addr addr; diff --git a/src/arch/mips/stacktrace.hh b/src/arch/mips/stacktrace.hh index e2424523f..4c02cc86c 100644 --- a/src/arch/mips/stacktrace.hh +++ b/src/arch/mips/stacktrace.hh @@ -61,7 +61,7 @@ class ProcessInfo class StackTrace { protected: - typedef TheISA::MachInst MachInst; + typedef MipsISA::MachInst MachInst; private: ThreadContext *tc; std::vector stack; diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 6e490e05e..a8fda04eb 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -354,7 +354,7 @@ SparcLiveProcess::argsInit(int pageSize) // figure out argc IntType argc = argv.size(); - IntType guestArgc = TheISA::htog(argc); + IntType guestArgc = SparcISA::htog(argc); //Write out the sentry void * uint64_t sentry_NULL = 0; diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc index d6be52424..76516daca 100644 --- a/src/arch/sparc/regfile.cc +++ b/src/arch/sparc/regfile.cc @@ -366,12 +366,12 @@ void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest) void SparcISA::copyRegs(ThreadContext *src, ThreadContext *dest) { // First loop through the integer registers. - for (int i = 0; i < TheISA::NumIntRegs; ++i) { + for (int i = 0; i < SparcISA::NumIntRegs; ++i) { dest->setIntReg(i, src->readIntReg(i)); } // Then loop through the floating point registers. - for (int i = 0; i < TheISA::NumFloatRegs; ++i) { + for (int i = 0; i < SparcISA::NumFloatRegs; ++i) { dest->setFloatRegBits(i, src->readFloatRegBits(i)); } diff --git a/src/arch/sparc/remote_gdb.cc b/src/arch/sparc/remote_gdb.cc index ef30bd808..615c5b551 100644 --- a/src/arch/sparc/remote_gdb.cc +++ b/src/arch/sparc/remote_gdb.cc @@ -137,7 +137,7 @@ #include "sim/system.hh" using namespace std; -using namespace TheISA; +using namespace SparcISA; RemoteGDB::RemoteGDB(System *_system, ThreadContext *c) : BaseRemoteGDB(_system, c, NumGDBRegs), nextBkpt(0) diff --git a/src/arch/sparc/stacktrace.cc b/src/arch/sparc/stacktrace.cc index 8ec1d36c8..3ab0edb57 100644 --- a/src/arch/sparc/stacktrace.cc +++ b/src/arch/sparc/stacktrace.cc @@ -159,7 +159,7 @@ namespace SparcISA } SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; - Addr ksp = tc->readIntReg(TheISA::StackPointerReg); + Addr ksp = tc->readIntReg(SparcISA::StackPointerReg); Addr bottom = ksp & ~0x3fff; Addr addr; diff --git a/src/arch/sparc/stacktrace.hh b/src/arch/sparc/stacktrace.hh index 4bc5d779b..929990fcb 100644 --- a/src/arch/sparc/stacktrace.hh +++ b/src/arch/sparc/stacktrace.hh @@ -61,7 +61,7 @@ namespace SparcISA class StackTrace { protected: - typedef TheISA::MachInst MachInst; + typedef SparcISA::MachInst MachInst; private: ThreadContext *tc; std::vector stack; diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 76f0b5d04..b62efd3cd 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -105,8 +105,8 @@ using namespace X86ISA; M5_64_auxv_t::M5_64_auxv_t(int64_t type, int64_t val) { - a_type = TheISA::htog(type); - a_val = TheISA::htog(val); + a_type = X86ISA::htog(type); + a_val = X86ISA::htog(val); } X86LiveProcess::X86LiveProcess(LiveProcessParams * params, @@ -424,7 +424,7 @@ X86LiveProcess::argsInit(int intSize, int pageSize) // figure out argc uint64_t argc = argv.size(); - uint64_t guestArgc = TheISA::htog(argc); + uint64_t guestArgc = X86ISA::htog(argc); //Write out the sentry void * uint64_t sentry_NULL = 0; diff --git a/src/arch/x86/remote_gdb.cc b/src/arch/x86/remote_gdb.cc index 3a024e087..c416042c8 100644 --- a/src/arch/x86/remote_gdb.cc +++ b/src/arch/x86/remote_gdb.cc @@ -157,7 +157,7 @@ #include "cpu/thread_context.hh" using namespace std; -using namespace TheISA; +using namespace X86ISA; RemoteGDB::RemoteGDB(System *_system, ThreadContext *c) : BaseRemoteGDB(_system, c, NumGDBRegs) -- cgit v1.2.3 From 82f5723c7a8b245e1f60190a78b7fe383c2caf9b Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 27 Sep 2008 21:03:47 -0700 Subject: alpha: Clean up namespace usage. --- src/arch/alpha/ev5.cc | 367 +++++++++++++++++++++-------------------- src/arch/alpha/ev5.hh | 14 +- src/arch/alpha/faults.cc | 28 ++-- src/arch/alpha/faults.hh | 14 +- src/arch/alpha/idle_event.cc | 2 +- src/arch/alpha/interrupts.hh | 2 +- src/arch/alpha/intregfile.cc | 4 +- src/arch/alpha/isa/decoder.isa | 8 +- src/arch/alpha/isa/fp.isa | 4 +- src/arch/alpha/isa/main.isa | 6 +- src/arch/alpha/kernel_stats.cc | 6 +- src/arch/alpha/kernel_stats.hh | 4 +- src/arch/alpha/pagetable.hh | 6 +- src/arch/alpha/regfile.cc | 18 +- src/arch/alpha/remote_gdb.cc | 36 ++-- src/arch/alpha/stacktrace.cc | 16 +- src/arch/alpha/stacktrace.hh | 2 - src/arch/alpha/system.cc | 13 +- src/arch/alpha/tlb.cc | 2 +- src/arch/alpha/tlb.hh | 4 +- src/arch/alpha/utility.hh | 2 +- src/arch/alpha/vtophys.cc | 37 +++-- src/arch/alpha/vtophys.hh | 2 +- 23 files changed, 300 insertions(+), 297 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index 45d2ff5a5..166d42bc6 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -44,7 +44,7 @@ #include "sim/debug.hh" #include "sim/sim_exit.hh" -using namespace AlphaISA; +namespace AlphaISA { #if FULL_SYSTEM @@ -53,14 +53,14 @@ using namespace AlphaISA; // Machine dependent functions // void -AlphaISA::initCPU(ThreadContext *tc, int cpuId) +initCPU(ThreadContext *tc, int cpuId) { initIPRs(tc, cpuId); tc->setIntReg(16, cpuId); tc->setIntReg(0, cpuId); - AlphaISA::AlphaFault *reset = new AlphaISA::ResetFault; + AlphaFault *reset = new ResetFault; tc->setPC(tc->readMiscRegNoEffect(IPR_PAL_BASE) + reset->vect()); tc->setNextPC(tc->readPC() + sizeof(MachInst)); @@ -71,7 +71,7 @@ AlphaISA::initCPU(ThreadContext *tc, int cpuId) template void -AlphaISA::processInterrupts(CPU *cpu) +processInterrupts(CPU *cpu) { //Check if there are any outstanding interrupts //Handle the interrupts @@ -117,7 +117,7 @@ AlphaISA::processInterrupts(CPU *cpu) template void -AlphaISA::zeroRegisters(CPU *cpu) +zeroRegisters(CPU *cpu) { // Insure ISA semantics // (no longer very clean due to the change in setIntReg() in the @@ -126,33 +126,16 @@ AlphaISA::zeroRegisters(CPU *cpu) cpu->thread->setFloatReg(ZeroReg, 0.0); } -Fault -SimpleThread::hwrei() -{ - if (!(readPC() & 0x3)) - return new UnimplementedOpcodeFault; - - setNextPC(readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR)); - - if (!misspeculating()) { - if (kernelStats) - kernelStats->hwrei(); - } - - // FIXME: XXX check for interrupts? XXX - return NoFault; -} - int -AlphaISA::MiscRegFile::getInstAsid() +MiscRegFile::getInstAsid() { - return AlphaISA::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); + return ITB_ASN_ASN(ipr[IPR_ITB_ASN]); } int -AlphaISA::MiscRegFile::getDataAsid() +MiscRegFile::getDataAsid() { - return AlphaISA::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); + return DTB_ASN_ASN(ipr[IPR_DTB_ASN]); } #endif @@ -162,90 +145,90 @@ AlphaISA::MiscRegFile::getDataAsid() // // void -AlphaISA::initIPRs(ThreadContext *tc, int cpuId) +initIPRs(ThreadContext *tc, int cpuId) { for (int i = 0; i < NumInternalProcRegs; ++i) { tc->setMiscRegNoEffect(i, 0); } - tc->setMiscRegNoEffect(IPR_PAL_BASE, AlphaISA::PalBase); + tc->setMiscRegNoEffect(IPR_PAL_BASE, PalBase); tc->setMiscRegNoEffect(IPR_MCSR, 0x6); tc->setMiscRegNoEffect(IPR_PALtemp16, cpuId); } -AlphaISA::MiscReg -AlphaISA::MiscRegFile::readIpr(int idx, ThreadContext *tc) +MiscReg +MiscRegFile::readIpr(int idx, ThreadContext *tc) { uint64_t retval = 0; // return value, default 0 switch (idx) { - case AlphaISA::IPR_PALtemp0: - case AlphaISA::IPR_PALtemp1: - case AlphaISA::IPR_PALtemp2: - case AlphaISA::IPR_PALtemp3: - case AlphaISA::IPR_PALtemp4: - case AlphaISA::IPR_PALtemp5: - case AlphaISA::IPR_PALtemp6: - case AlphaISA::IPR_PALtemp7: - case AlphaISA::IPR_PALtemp8: - case AlphaISA::IPR_PALtemp9: - case AlphaISA::IPR_PALtemp10: - case AlphaISA::IPR_PALtemp11: - case AlphaISA::IPR_PALtemp12: - case AlphaISA::IPR_PALtemp13: - case AlphaISA::IPR_PALtemp14: - case AlphaISA::IPR_PALtemp15: - case AlphaISA::IPR_PALtemp16: - case AlphaISA::IPR_PALtemp17: - case AlphaISA::IPR_PALtemp18: - case AlphaISA::IPR_PALtemp19: - case AlphaISA::IPR_PALtemp20: - case AlphaISA::IPR_PALtemp21: - case AlphaISA::IPR_PALtemp22: - case AlphaISA::IPR_PALtemp23: - case AlphaISA::IPR_PAL_BASE: - - case AlphaISA::IPR_IVPTBR: - case AlphaISA::IPR_DC_MODE: - case AlphaISA::IPR_MAF_MODE: - case AlphaISA::IPR_ISR: - case AlphaISA::IPR_EXC_ADDR: - case AlphaISA::IPR_IC_PERR_STAT: - case AlphaISA::IPR_DC_PERR_STAT: - case AlphaISA::IPR_MCSR: - case AlphaISA::IPR_ASTRR: - case AlphaISA::IPR_ASTER: - case AlphaISA::IPR_SIRR: - case AlphaISA::IPR_ICSR: - case AlphaISA::IPR_ICM: - case AlphaISA::IPR_DTB_CM: - case AlphaISA::IPR_IPLR: - case AlphaISA::IPR_INTID: - case AlphaISA::IPR_PMCTR: + case IPR_PALtemp0: + case IPR_PALtemp1: + case IPR_PALtemp2: + case IPR_PALtemp3: + case IPR_PALtemp4: + case IPR_PALtemp5: + case IPR_PALtemp6: + case IPR_PALtemp7: + case IPR_PALtemp8: + case IPR_PALtemp9: + case IPR_PALtemp10: + case IPR_PALtemp11: + case IPR_PALtemp12: + case IPR_PALtemp13: + case IPR_PALtemp14: + case IPR_PALtemp15: + case IPR_PALtemp16: + case IPR_PALtemp17: + case IPR_PALtemp18: + case IPR_PALtemp19: + case IPR_PALtemp20: + case IPR_PALtemp21: + case IPR_PALtemp22: + case IPR_PALtemp23: + case IPR_PAL_BASE: + + case IPR_IVPTBR: + case IPR_DC_MODE: + case IPR_MAF_MODE: + case IPR_ISR: + case IPR_EXC_ADDR: + case IPR_IC_PERR_STAT: + case IPR_DC_PERR_STAT: + case IPR_MCSR: + case IPR_ASTRR: + case IPR_ASTER: + case IPR_SIRR: + case IPR_ICSR: + case IPR_ICM: + case IPR_DTB_CM: + case IPR_IPLR: + case IPR_INTID: + case IPR_PMCTR: // no side-effect retval = ipr[idx]; break; - case AlphaISA::IPR_CC: + case IPR_CC: retval |= ipr[idx] & ULL(0xffffffff00000000); retval |= tc->getCpuPtr()->curCycle() & ULL(0x00000000ffffffff); break; - case AlphaISA::IPR_VA: + case IPR_VA: retval = ipr[idx]; break; - case AlphaISA::IPR_VA_FORM: - case AlphaISA::IPR_MM_STAT: - case AlphaISA::IPR_IFAULT_VA_FORM: - case AlphaISA::IPR_EXC_MASK: - case AlphaISA::IPR_EXC_SUM: + case IPR_VA_FORM: + case IPR_MM_STAT: + case IPR_IFAULT_VA_FORM: + case IPR_EXC_MASK: + case IPR_EXC_SUM: retval = ipr[idx]; break; - case AlphaISA::IPR_DTB_PTE: + case IPR_DTB_PTE: { - AlphaISA::TlbEntry &entry + TlbEntry &entry = tc->getDTBPtr()->index(!tc->misspeculating()); retval |= ((uint64_t)entry.ppn & ULL(0x7ffffff)) << 32; @@ -259,15 +242,15 @@ AlphaISA::MiscRegFile::readIpr(int idx, ThreadContext *tc) break; // write only registers - case AlphaISA::IPR_HWINT_CLR: - case AlphaISA::IPR_SL_XMIT: - case AlphaISA::IPR_DC_FLUSH: - case AlphaISA::IPR_IC_FLUSH: - case AlphaISA::IPR_ALT_MODE: - case AlphaISA::IPR_DTB_IA: - case AlphaISA::IPR_DTB_IAP: - case AlphaISA::IPR_ITB_IA: - case AlphaISA::IPR_ITB_IAP: + case IPR_HWINT_CLR: + case IPR_SL_XMIT: + case IPR_DC_FLUSH: + case IPR_IC_FLUSH: + case IPR_ALT_MODE: + case IPR_DTB_IA: + case IPR_DTB_IAP: + case IPR_ITB_IA: + case IPR_ITB_IAP: panic("Tried to read write only register %d\n", idx); break; @@ -286,7 +269,7 @@ int break_ipl = -1; #endif void -AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) +MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) { uint64_t old; @@ -294,52 +277,52 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) return; switch (idx) { - case AlphaISA::IPR_PALtemp0: - case AlphaISA::IPR_PALtemp1: - case AlphaISA::IPR_PALtemp2: - case AlphaISA::IPR_PALtemp3: - case AlphaISA::IPR_PALtemp4: - case AlphaISA::IPR_PALtemp5: - case AlphaISA::IPR_PALtemp6: - case AlphaISA::IPR_PALtemp7: - case AlphaISA::IPR_PALtemp8: - case AlphaISA::IPR_PALtemp9: - case AlphaISA::IPR_PALtemp10: - case AlphaISA::IPR_PALtemp11: - case AlphaISA::IPR_PALtemp12: - case AlphaISA::IPR_PALtemp13: - case AlphaISA::IPR_PALtemp14: - case AlphaISA::IPR_PALtemp15: - case AlphaISA::IPR_PALtemp16: - case AlphaISA::IPR_PALtemp17: - case AlphaISA::IPR_PALtemp18: - case AlphaISA::IPR_PALtemp19: - case AlphaISA::IPR_PALtemp20: - case AlphaISA::IPR_PALtemp21: - case AlphaISA::IPR_PALtemp22: - case AlphaISA::IPR_PAL_BASE: - case AlphaISA::IPR_IC_PERR_STAT: - case AlphaISA::IPR_DC_PERR_STAT: - case AlphaISA::IPR_PMCTR: + case IPR_PALtemp0: + case IPR_PALtemp1: + case IPR_PALtemp2: + case IPR_PALtemp3: + case IPR_PALtemp4: + case IPR_PALtemp5: + case IPR_PALtemp6: + case IPR_PALtemp7: + case IPR_PALtemp8: + case IPR_PALtemp9: + case IPR_PALtemp10: + case IPR_PALtemp11: + case IPR_PALtemp12: + case IPR_PALtemp13: + case IPR_PALtemp14: + case IPR_PALtemp15: + case IPR_PALtemp16: + case IPR_PALtemp17: + case IPR_PALtemp18: + case IPR_PALtemp19: + case IPR_PALtemp20: + case IPR_PALtemp21: + case IPR_PALtemp22: + case IPR_PAL_BASE: + case IPR_IC_PERR_STAT: + case IPR_DC_PERR_STAT: + case IPR_PMCTR: // write entire quad w/ no side-effect ipr[idx] = val; break; - case AlphaISA::IPR_CC_CTL: + case IPR_CC_CTL: // This IPR resets the cycle counter. We assume this only // happens once... let's verify that. assert(ipr[idx] == 0); ipr[idx] = 1; break; - case AlphaISA::IPR_CC: + case IPR_CC: // This IPR only writes the upper 64 bits. It's ok to write // all 64 here since we mask out the lower 32 in rpcc (see // isa_desc). ipr[idx] = val; break; - case AlphaISA::IPR_PALtemp23: + case IPR_PALtemp23: // write entire quad w/ no side-effect old = ipr[idx]; ipr[idx] = val; @@ -349,23 +332,23 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) #endif break; - case AlphaISA::IPR_DTB_PTE: + case IPR_DTB_PTE: // write entire quad w/ no side-effect, tag is forthcoming ipr[idx] = val; break; - case AlphaISA::IPR_EXC_ADDR: + case IPR_EXC_ADDR: // second least significant bit in PC is always zero ipr[idx] = val & ~2; break; - case AlphaISA::IPR_ASTRR: - case AlphaISA::IPR_ASTER: + case IPR_ASTRR: + case IPR_ASTER: // only write least significant four bits - privilege mask ipr[idx] = val & 0xf; break; - case AlphaISA::IPR_IPLR: + case IPR_IPLR: #ifdef DEBUG if (break_ipl != -1 && break_ipl == (val & 0x1f)) debug_break(); @@ -379,175 +362,175 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) #endif break; - case AlphaISA::IPR_DTB_CM: + case IPR_DTB_CM: #if FULL_SYSTEM if (val & 0x18) { if (tc->getKernelStats()) - tc->getKernelStats()->mode(AlphaISA::Kernel::user, tc); + tc->getKernelStats()->mode(Kernel::user, tc); } else { if (tc->getKernelStats()) - tc->getKernelStats()->mode(AlphaISA::Kernel::kernel, tc); + tc->getKernelStats()->mode(Kernel::kernel, tc); } #endif - case AlphaISA::IPR_ICM: + case IPR_ICM: // only write two mode bits - processor mode ipr[idx] = val & 0x18; break; - case AlphaISA::IPR_ALT_MODE: + case IPR_ALT_MODE: // only write two mode bits - processor mode ipr[idx] = val & 0x18; break; - case AlphaISA::IPR_MCSR: + case IPR_MCSR: // more here after optimization... ipr[idx] = val; break; - case AlphaISA::IPR_SIRR: + case IPR_SIRR: // only write software interrupt mask ipr[idx] = val & 0x7fff0; break; - case AlphaISA::IPR_ICSR: + case IPR_ICSR: ipr[idx] = val & ULL(0xffffff0300); break; - case AlphaISA::IPR_IVPTBR: - case AlphaISA::IPR_MVPTBR: + case IPR_IVPTBR: + case IPR_MVPTBR: ipr[idx] = val & ULL(0xffffffffc0000000); break; - case AlphaISA::IPR_DC_TEST_CTL: + case IPR_DC_TEST_CTL: ipr[idx] = val & 0x1ffb; break; - case AlphaISA::IPR_DC_MODE: - case AlphaISA::IPR_MAF_MODE: + case IPR_DC_MODE: + case IPR_MAF_MODE: ipr[idx] = val & 0x3f; break; - case AlphaISA::IPR_ITB_ASN: + case IPR_ITB_ASN: ipr[idx] = val & 0x7f0; break; - case AlphaISA::IPR_DTB_ASN: + case IPR_DTB_ASN: ipr[idx] = val & ULL(0xfe00000000000000); break; - case AlphaISA::IPR_EXC_SUM: - case AlphaISA::IPR_EXC_MASK: + case IPR_EXC_SUM: + case IPR_EXC_MASK: // any write to this register clears it ipr[idx] = 0; break; - case AlphaISA::IPR_INTID: - case AlphaISA::IPR_SL_RCV: - case AlphaISA::IPR_MM_STAT: - case AlphaISA::IPR_ITB_PTE_TEMP: - case AlphaISA::IPR_DTB_PTE_TEMP: + case IPR_INTID: + case IPR_SL_RCV: + case IPR_MM_STAT: + case IPR_ITB_PTE_TEMP: + case IPR_DTB_PTE_TEMP: // read-only registers panic("Tried to write read only ipr %d\n", idx); - case AlphaISA::IPR_HWINT_CLR: - case AlphaISA::IPR_SL_XMIT: - case AlphaISA::IPR_DC_FLUSH: - case AlphaISA::IPR_IC_FLUSH: + case IPR_HWINT_CLR: + case IPR_SL_XMIT: + case IPR_DC_FLUSH: + case IPR_IC_FLUSH: // the following are write only ipr[idx] = val; break; - case AlphaISA::IPR_DTB_IA: + case IPR_DTB_IA: // really a control write ipr[idx] = 0; tc->getDTBPtr()->flushAll(); break; - case AlphaISA::IPR_DTB_IAP: + case IPR_DTB_IAP: // really a control write ipr[idx] = 0; tc->getDTBPtr()->flushProcesses(); break; - case AlphaISA::IPR_DTB_IS: + case IPR_DTB_IS: // really a control write ipr[idx] = val; tc->getDTBPtr()->flushAddr(val, - AlphaISA::DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); + DTB_ASN_ASN(ipr[IPR_DTB_ASN])); break; - case AlphaISA::IPR_DTB_TAG: { - struct AlphaISA::TlbEntry entry; + case IPR_DTB_TAG: { + struct TlbEntry entry; // FIXME: granularity hints NYI... - if (AlphaISA::DTB_PTE_GH(ipr[AlphaISA::IPR_DTB_PTE]) != 0) + if (DTB_PTE_GH(ipr[IPR_DTB_PTE]) != 0) panic("PTE GH field != 0"); // write entire quad ipr[idx] = val; // construct PTE for new entry - entry.ppn = AlphaISA::DTB_PTE_PPN(ipr[AlphaISA::IPR_DTB_PTE]); - entry.xre = AlphaISA::DTB_PTE_XRE(ipr[AlphaISA::IPR_DTB_PTE]); - entry.xwe = AlphaISA::DTB_PTE_XWE(ipr[AlphaISA::IPR_DTB_PTE]); - entry.fonr = AlphaISA::DTB_PTE_FONR(ipr[AlphaISA::IPR_DTB_PTE]); - entry.fonw = AlphaISA::DTB_PTE_FONW(ipr[AlphaISA::IPR_DTB_PTE]); - entry.asma = AlphaISA::DTB_PTE_ASMA(ipr[AlphaISA::IPR_DTB_PTE]); - entry.asn = AlphaISA::DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]); + entry.ppn = DTB_PTE_PPN(ipr[IPR_DTB_PTE]); + entry.xre = DTB_PTE_XRE(ipr[IPR_DTB_PTE]); + entry.xwe = DTB_PTE_XWE(ipr[IPR_DTB_PTE]); + entry.fonr = DTB_PTE_FONR(ipr[IPR_DTB_PTE]); + entry.fonw = DTB_PTE_FONW(ipr[IPR_DTB_PTE]); + entry.asma = DTB_PTE_ASMA(ipr[IPR_DTB_PTE]); + entry.asn = DTB_ASN_ASN(ipr[IPR_DTB_ASN]); // insert new TAG/PTE value into data TLB tc->getDTBPtr()->insert(val, entry); } break; - case AlphaISA::IPR_ITB_PTE: { - struct AlphaISA::TlbEntry entry; + case IPR_ITB_PTE: { + struct TlbEntry entry; // FIXME: granularity hints NYI... - if (AlphaISA::ITB_PTE_GH(val) != 0) + if (ITB_PTE_GH(val) != 0) panic("PTE GH field != 0"); // write entire quad ipr[idx] = val; // construct PTE for new entry - entry.ppn = AlphaISA::ITB_PTE_PPN(val); - entry.xre = AlphaISA::ITB_PTE_XRE(val); + entry.ppn = ITB_PTE_PPN(val); + entry.xre = ITB_PTE_XRE(val); entry.xwe = 0; - entry.fonr = AlphaISA::ITB_PTE_FONR(val); - entry.fonw = AlphaISA::ITB_PTE_FONW(val); - entry.asma = AlphaISA::ITB_PTE_ASMA(val); - entry.asn = AlphaISA::ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]); + entry.fonr = ITB_PTE_FONR(val); + entry.fonw = ITB_PTE_FONW(val); + entry.asma = ITB_PTE_ASMA(val); + entry.asn = ITB_ASN_ASN(ipr[IPR_ITB_ASN]); // insert new TAG/PTE value into data TLB - tc->getITBPtr()->insert(ipr[AlphaISA::IPR_ITB_TAG], entry); + tc->getITBPtr()->insert(ipr[IPR_ITB_TAG], entry); } break; - case AlphaISA::IPR_ITB_IA: + case IPR_ITB_IA: // really a control write ipr[idx] = 0; tc->getITBPtr()->flushAll(); break; - case AlphaISA::IPR_ITB_IAP: + case IPR_ITB_IAP: // really a control write ipr[idx] = 0; tc->getITBPtr()->flushProcesses(); break; - case AlphaISA::IPR_ITB_IS: + case IPR_ITB_IS: // really a control write ipr[idx] = val; tc->getITBPtr()->flushAddr(val, - AlphaISA::ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN])); + ITB_ASN_ASN(ipr[IPR_ITB_ASN])); break; default: @@ -560,14 +543,34 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) void -AlphaISA::copyIprs(ThreadContext *src, ThreadContext *dest) +copyIprs(ThreadContext *src, ThreadContext *dest) { for (int i = 0; i < NumInternalProcRegs; ++i) { dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i)); } } +} // namespace AlphaISA + #if FULL_SYSTEM +using namespace AlphaISA; + +Fault +SimpleThread::hwrei() +{ + if (!(readPC() & 0x3)) + return new UnimplementedOpcodeFault; + + setNextPC(readMiscRegNoEffect(IPR_EXC_ADDR)); + + if (!misspeculating()) { + if (kernelStats) + kernelStats->hwrei(); + } + + // FIXME: XXX check for interrupts? XXX + return NoFault; +} /** * Check for special simulator handling of specific PAL calls. diff --git a/src/arch/alpha/ev5.hh b/src/arch/alpha/ev5.hh index 4fe5f1b71..a40ca6749 100644 --- a/src/arch/alpha/ev5.hh +++ b/src/arch/alpha/ev5.hh @@ -48,8 +48,8 @@ const int VAddrImplBits = 43; const Addr VAddrImplMask = (ULL(1) << VAddrImplBits) - 1; const Addr VAddrUnImplMask = ~VAddrImplMask; inline Addr VAddrImpl(Addr a) { return a & VAddrImplMask; } -inline Addr VAddrVPN(Addr a) { return a >> AlphaISA::PageShift; } -inline Addr VAddrOffset(Addr a) { return a & AlphaISA::PageOffset; } +inline Addr VAddrVPN(Addr a) { return a >> PageShift; } +inline Addr VAddrOffset(Addr a) { return a & PageOffset; } inline Addr VAddrSpaceEV5(Addr a) { return a >> 41 & 0x3; } inline Addr VAddrSpaceEV6(Addr a) { return a >> 41 & 0x7f; } @@ -73,12 +73,12 @@ inline Addr Phys2K0Seg(Addr addr) addr |= PAddrUncachedBit40; } #endif - return addr | AlphaISA::K0SegBase; + return addr | K0SegBase; } inline int DTB_ASN_ASN(uint64_t reg) { return reg >> 57 & AsnMask; } inline Addr DTB_PTE_PPN(uint64_t reg) -{ return reg >> 32 & (ULL(1) << PAddrImplBits - AlphaISA::PageShift) - 1; } +{ return reg >> 32 & (ULL(1) << PAddrImplBits - PageShift) - 1; } inline int DTB_PTE_XRE(uint64_t reg) { return reg >> 8 & 0xf; } inline int DTB_PTE_XWE(uint64_t reg) { return reg >> 12 & 0xf; } inline int DTB_PTE_FONR(uint64_t reg) { return reg >> 1 & 0x1; } @@ -88,7 +88,7 @@ inline int DTB_PTE_ASMA(uint64_t reg) { return reg >> 4 & 0x1; } inline int ITB_ASN_ASN(uint64_t reg) { return reg >> 4 & AsnMask; } inline Addr ITB_PTE_PPN(uint64_t reg) -{ return reg >> 32 & (ULL(1) << PAddrImplBits - AlphaISA::PageShift) - 1; } +{ return reg >> 32 & (ULL(1) << PAddrImplBits - PageShift) - 1; } inline int ITB_PTE_XRE(uint64_t reg) { return reg >> 8 & 0xf; } inline bool ITB_PTE_FONR(uint64_t reg) { return reg >> 1 & 0x1; } inline bool ITB_PTE_FONW(uint64_t reg) { return reg >> 2 & 0x1; } @@ -111,8 +111,8 @@ const uint64_t MM_STAT_FONW_MASK = ULL(0x0008); const uint64_t MM_STAT_FONR_MASK = ULL(0x0004); const uint64_t MM_STAT_ACV_MASK = ULL(0x0002); const uint64_t MM_STAT_WR_MASK = ULL(0x0001); -inline int Opcode(AlphaISA::MachInst inst) { return inst >> 26 & 0x3f; } -inline int Ra(AlphaISA::MachInst inst) { return inst >> 21 & 0x1f; } +inline int Opcode(MachInst inst) { return inst >> 26 & 0x3f; } +inline int Ra(MachInst inst) { return inst >> 21 & 0x1f; } const Addr PalBase = 0x4000; const Addr PalMax = 0x10000; diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc index 7417ada5f..845ac0288 100644 --- a/src/arch/alpha/faults.cc +++ b/src/arch/alpha/faults.cc @@ -116,15 +116,15 @@ void AlphaFault::invoke(ThreadContext * tc) // exception restart address if (setRestartAddress() || !(tc->readPC() & 0x3)) - tc->setMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR, tc->readPC()); + tc->setMiscRegNoEffect(IPR_EXC_ADDR, tc->readPC()); if (skipFaultingInstruction()) { // traps... skip faulting instruction. - tc->setMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR, - tc->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR) + 4); + tc->setMiscRegNoEffect(IPR_EXC_ADDR, + tc->readMiscRegNoEffect(IPR_EXC_ADDR) + 4); } - tc->setPC(tc->readMiscRegNoEffect(AlphaISA::IPR_PAL_BASE) + vect()); + tc->setPC(tc->readMiscRegNoEffect(IPR_PAL_BASE) + vect()); tc->setNextPC(tc->readPC() + sizeof(MachInst)); } @@ -144,17 +144,17 @@ void DtbFault::invoke(ThreadContext * tc) if (!tc->misspeculating() && !(reqFlags & VPTE) && !(reqFlags & NO_FAULT)) { // set VA register with faulting address - tc->setMiscRegNoEffect(AlphaISA::IPR_VA, vaddr); + tc->setMiscRegNoEffect(IPR_VA, vaddr); // set MM_STAT register flags - tc->setMiscRegNoEffect(AlphaISA::IPR_MM_STAT, - (((AlphaISA::Opcode(tc->getInst()) & 0x3f) << 11) - | ((AlphaISA::Ra(tc->getInst()) & 0x1f) << 6) + tc->setMiscRegNoEffect(IPR_MM_STAT, + (((Opcode(tc->getInst()) & 0x3f) << 11) + | ((Ra(tc->getInst()) & 0x1f) << 6) | (flags & 0x3f))); // set VA_FORM register with faulting formatted address - tc->setMiscRegNoEffect(AlphaISA::IPR_VA_FORM, - tc->readMiscRegNoEffect(AlphaISA::IPR_MVPTBR) | (vaddr.vpn() << 3)); + tc->setMiscRegNoEffect(IPR_VA_FORM, + tc->readMiscRegNoEffect(IPR_MVPTBR) | (vaddr.vpn() << 3)); } AlphaFault::invoke(tc); @@ -163,10 +163,10 @@ void DtbFault::invoke(ThreadContext * tc) void ItbFault::invoke(ThreadContext * tc) { if (!tc->misspeculating()) { - tc->setMiscRegNoEffect(AlphaISA::IPR_ITB_TAG, pc); - tc->setMiscRegNoEffect(AlphaISA::IPR_IFAULT_VA_FORM, - tc->readMiscRegNoEffect(AlphaISA::IPR_IVPTBR) | - (AlphaISA::VAddr(pc).vpn() << 3)); + tc->setMiscRegNoEffect(IPR_ITB_TAG, pc); + tc->setMiscRegNoEffect(IPR_IFAULT_VA_FORM, + tc->readMiscRegNoEffect(IPR_IVPTBR) | + (VAddr(pc).vpn() << 3)); } AlphaFault::invoke(tc); diff --git a/src/arch/alpha/faults.hh b/src/arch/alpha/faults.hh index 74699b2b5..1d2ac593a 100644 --- a/src/arch/alpha/faults.hh +++ b/src/arch/alpha/faults.hh @@ -134,11 +134,11 @@ class InterruptFault : public AlphaFault class DtbFault : public AlphaFault { protected: - AlphaISA::VAddr vaddr; + VAddr vaddr; uint32_t reqFlags; uint64_t flags; public: - DtbFault(AlphaISA::VAddr _vaddr, uint32_t _reqFlags, uint64_t _flags) + DtbFault(VAddr _vaddr, uint32_t _reqFlags, uint64_t _flags) : vaddr(_vaddr), reqFlags(_reqFlags), flags(_flags) { } FaultName name() const = 0; @@ -156,7 +156,7 @@ class NDtbMissFault : public DtbFault static FaultVect _vect; static FaultStat _count; public: - NDtbMissFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags) + NDtbMissFault(VAddr vaddr, uint32_t reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) { } FaultName name() const {return _name;} @@ -174,7 +174,7 @@ class PDtbMissFault : public DtbFault static FaultVect _vect; static FaultStat _count; public: - PDtbMissFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags) + PDtbMissFault(VAddr vaddr, uint32_t reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) { } FaultName name() const {return _name;} @@ -189,7 +189,7 @@ class DtbPageFault : public DtbFault static FaultVect _vect; static FaultStat _count; public: - DtbPageFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags) + DtbPageFault(VAddr vaddr, uint32_t reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) { } FaultName name() const {return _name;} @@ -204,7 +204,7 @@ class DtbAcvFault : public DtbFault static FaultVect _vect; static FaultStat _count; public: - DtbAcvFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags) + DtbAcvFault(VAddr vaddr, uint32_t reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) { } FaultName name() const {return _name;} @@ -219,7 +219,7 @@ class DtbAlignmentFault : public DtbFault static FaultVect _vect; static FaultStat _count; public: - DtbAlignmentFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags) + DtbAlignmentFault(VAddr vaddr, uint32_t reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) { } FaultName name() const {return _name;} diff --git a/src/arch/alpha/idle_event.cc b/src/arch/alpha/idle_event.cc index d3807a48d..337166aec 100644 --- a/src/arch/alpha/idle_event.cc +++ b/src/arch/alpha/idle_event.cc @@ -40,6 +40,6 @@ IdleStartEvent::process(ThreadContext *tc) { if (tc->getKernelStats()) tc->getKernelStats()->setIdleProcess( - tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23), tc); + tc->readMiscRegNoEffect(IPR_PALtemp23), tc); remove(); } diff --git a/src/arch/alpha/interrupts.hh b/src/arch/alpha/interrupts.hh index 1d8ba736f..abfecfb5b 100644 --- a/src/arch/alpha/interrupts.hh +++ b/src/arch/alpha/interrupts.hh @@ -78,7 +78,7 @@ class Interrupts { DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); - if (int_num < 0 || int_num >= AlphaISA::NumInterruptLevels) + if (int_num < 0 || int_num >= NumInterruptLevels) panic("int_num out of bounds\n"); if (index < 0 || index >= (int)sizeof(uint64_t) * 8) diff --git a/src/arch/alpha/intregfile.cc b/src/arch/alpha/intregfile.cc index 0188cb2cd..d1dfc5168 100644 --- a/src/arch/alpha/intregfile.cc +++ b/src/arch/alpha/intregfile.cc @@ -37,13 +37,13 @@ namespace AlphaISA { #if FULL_SYSTEM - const int reg_redir[AlphaISA::NumIntRegs] = { + const int reg_redir[NumIntRegs] = { /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, /* 8 */ 32, 33, 34, 35, 36, 37, 38, 15, /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23, /* 24 */ 24, 39, 26, 27, 28, 29, 30, 31 }; #else - const int reg_redir[AlphaISA::NumIntRegs] = { + const int reg_redir[NumIntRegs] = { /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, /* 8 */ 8, 9, 10, 11, 12, 13, 14, 15, /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23, diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index dc30039b2..270940df2 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -638,7 +638,7 @@ decode OPCODE default Unknown::unknown() { /* Rb is a fake dependency so here is a fun way to get * the parser to understand that. */ - Ra = xc->readMiscReg(AlphaISA::IPR_CC) + (Rb & 0); + Ra = xc->readMiscReg(IPR_CC) + (Rb & 0); #else Ra = curTick; @@ -690,7 +690,7 @@ decode OPCODE default Unknown::unknown() { 0x00: CallPal::call_pal({{ if (!palValid || (palPriv - && xc->readMiscReg(AlphaISA::IPR_ICM) != AlphaISA::mode_kernel)) { + && xc->readMiscReg(IPR_ICM) != mode_kernel)) { // invalid pal function code, or attempt to do privileged // PAL call in non-kernel mode fault = new UnimplementedOpcodeFault; @@ -701,8 +701,8 @@ decode OPCODE default Unknown::unknown() { bool dopal = xc->simPalCheck(palFunc); if (dopal) { - xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, NPC); - NPC = xc->readMiscReg(AlphaISA::IPR_PAL_BASE) + palOffset; + xc->setMiscReg(IPR_EXC_ADDR, NPC); + NPC = xc->readMiscReg(IPR_PAL_BASE) + palOffset; } } }}, IsNonSpeculative); diff --git a/src/arch/alpha/isa/fp.isa b/src/arch/alpha/isa/fp.isa index 8b13f8dd7..ed04d2a50 100644 --- a/src/arch/alpha/isa/fp.isa +++ b/src/arch/alpha/isa/fp.isa @@ -46,7 +46,7 @@ output exec {{ inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) { Fault fault = NoFault; // dummy... this ipr access should not fault - if (!AlphaISA::ICSR_FPE(xc->readMiscReg(AlphaISA::IPR_ICSR))) { + if (!ICSR_FPE(xc->readMiscReg(IPR_ICSR))) { fault = new FloatEnableFault; } return fault; @@ -229,7 +229,7 @@ def template FloatingPointExecute {{ %(code)s; } else { m5_fesetround(getC99RoundingMode( - xc->readMiscRegNoEffect(AlphaISA::MISCREG_FPCR))); + xc->readMiscRegNoEffect(MISCREG_FPCR))); %(code)s; m5_fesetround(M5_FE_TONEAREST); } diff --git a/src/arch/alpha/isa/main.isa b/src/arch/alpha/isa/main.isa index d72dfe34a..5231712c8 100644 --- a/src/arch/alpha/isa/main.isa +++ b/src/arch/alpha/isa/main.isa @@ -173,11 +173,11 @@ def operands {{ # Int regs default to unsigned, but code should not count on this. # For clarity, descriptions that depend on unsigned behavior should # explicitly specify '.uq'. - 'Ra': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RA] : RA', + 'Ra': ('IntReg', 'uq', 'PALMODE ? reg_redir[RA] : RA', 'IsInteger', 1), - 'Rb': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RB] : RB', + 'Rb': ('IntReg', 'uq', 'PALMODE ? reg_redir[RB] : RB', 'IsInteger', 2), - 'Rc': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RC] : RC', + 'Rc': ('IntReg', 'uq', 'PALMODE ? reg_redir[RC] : RC', 'IsInteger', 3), 'Fa': ('FloatReg', 'df', 'FA', 'IsFloating', 1), 'Fb': ('FloatReg', 'df', 'FB', 'IsFloating', 2), diff --git a/src/arch/alpha/kernel_stats.cc b/src/arch/alpha/kernel_stats.cc index a004d5f25..6e9dc1611 100644 --- a/src/arch/alpha/kernel_stats.cc +++ b/src/arch/alpha/kernel_stats.cc @@ -152,7 +152,7 @@ Statistics::changeMode(cpu_mode newmode, ThreadContext *tc) void Statistics::mode(cpu_mode newmode, ThreadContext *tc) { - Addr pcbb = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23); + Addr pcbb = tc->readMiscRegNoEffect(IPR_PALtemp23); if (newmode == kernel && pcbb == idleProcess) newmode = idle; @@ -213,5 +213,5 @@ Statistics::unserialize(Checkpoint *cp, const string §ion) themode = (cpu_mode)exemode; } -} /* end namespace AlphaISA::Kernel */ -} /* end namespace AlphaISA */ +} // namespace Kernel +} // namespace AlphaISA diff --git a/src/arch/alpha/kernel_stats.hh b/src/arch/alpha/kernel_stats.hh index 7b8640ad7..aab96b150 100644 --- a/src/arch/alpha/kernel_stats.hh +++ b/src/arch/alpha/kernel_stats.hh @@ -90,7 +90,7 @@ class Statistics : public ::Kernel::Statistics void unserialize(Checkpoint *cp, const std::string §ion); }; -} /* end namespace AlphaISA::Kernel */ -} /* end namespace AlphaISA */ +} // namespace Kernel +} // namespace AlphaISA #endif // __ARCH_ALPHA_KERNEL_STATS_HH__ diff --git a/src/arch/alpha/pagetable.hh b/src/arch/alpha/pagetable.hh index f28c1b195..b0689dce0 100644 --- a/src/arch/alpha/pagetable.hh +++ b/src/arch/alpha/pagetable.hh @@ -54,11 +54,11 @@ namespace AlphaISA { Addr offset() const { return addr & PageOffset; } Addr level3() const - { return AlphaISA::PteAddr(addr >> PageShift); } + { return PteAddr(addr >> PageShift); } Addr level2() const - { return AlphaISA::PteAddr(addr >> NPtePageShift + PageShift); } + { return PteAddr(addr >> NPtePageShift + PageShift); } Addr level1() const - { return AlphaISA::PteAddr(addr >> 2 * NPtePageShift + PageShift); } + { return PteAddr(addr >> 2 * NPtePageShift + PageShift); } }; struct PageTableEntry diff --git a/src/arch/alpha/regfile.cc b/src/arch/alpha/regfile.cc index 3faa189ca..e617b00ae 100644 --- a/src/arch/alpha/regfile.cc +++ b/src/arch/alpha/regfile.cc @@ -70,7 +70,7 @@ namespace AlphaISA } // Then loop through the floating point registers. - for (int i = 0; i < AlphaISA::NumFloatRegs; ++i) { + for (int i = 0; i < NumFloatRegs; ++i) { dest->setFloatRegBits(i, src->readFloatRegBits(i)); } @@ -85,14 +85,14 @@ namespace AlphaISA void copyMiscRegs(ThreadContext *src, ThreadContext *dest) { - dest->setMiscRegNoEffect(AlphaISA::MISCREG_FPCR, - src->readMiscRegNoEffect(AlphaISA::MISCREG_FPCR)); - dest->setMiscRegNoEffect(AlphaISA::MISCREG_UNIQ, - src->readMiscRegNoEffect(AlphaISA::MISCREG_UNIQ)); - dest->setMiscRegNoEffect(AlphaISA::MISCREG_LOCKFLAG, - src->readMiscRegNoEffect(AlphaISA::MISCREG_LOCKFLAG)); - dest->setMiscRegNoEffect(AlphaISA::MISCREG_LOCKADDR, - src->readMiscRegNoEffect(AlphaISA::MISCREG_LOCKADDR)); + dest->setMiscRegNoEffect(MISCREG_FPCR, + src->readMiscRegNoEffect(MISCREG_FPCR)); + dest->setMiscRegNoEffect(MISCREG_UNIQ, + src->readMiscRegNoEffect(MISCREG_UNIQ)); + dest->setMiscRegNoEffect(MISCREG_LOCKFLAG, + src->readMiscRegNoEffect(MISCREG_LOCKFLAG)); + dest->setMiscRegNoEffect(MISCREG_LOCKADDR, + src->readMiscRegNoEffect(MISCREG_LOCKADDR)); copyIprs(src, dest); } diff --git a/src/arch/alpha/remote_gdb.cc b/src/arch/alpha/remote_gdb.cc index a40d06f18..22a1f5224 100644 --- a/src/arch/alpha/remote_gdb.cc +++ b/src/arch/alpha/remote_gdb.cc @@ -161,12 +161,12 @@ RemoteGDB::acc(Addr va, size_t len) #else Addr last_va; - va = AlphaISA::TruncPage(va); - last_va = AlphaISA::RoundPage(va + len); + va = TruncPage(va); + last_va = RoundPage(va + len); do { - if (AlphaISA::IsK0Seg(va)) { - if (va < (AlphaISA::K0SegBase + pmem->size())) { + if (IsK0Seg(va)) { + if (va < (K0SegBase + pmem->size())) { DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= " "%#x < K0SEG + size\n", va); return true; @@ -184,16 +184,16 @@ RemoteGDB::acc(Addr va, size_t len) * but there is no easy way to do it. */ - if (AlphaISA::PcPAL(va) || va < 0x10000) + if (PcPAL(va) || va < 0x10000) return true; - Addr ptbr = context->readMiscRegNoEffect(AlphaISA::IPR_PALtemp20); - AlphaISA::PageTableEntry pte = AlphaISA::kernel_pte_lookup(context->getPhysPort(), ptbr, va); + Addr ptbr = context->readMiscRegNoEffect(IPR_PALtemp20); + PageTableEntry pte = kernel_pte_lookup(context->getPhysPort(), ptbr, va); if (!pte.valid()) { DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va); return false; } - va += AlphaISA::PageBytes; + va += PageBytes; } while (va < last_va); DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va); @@ -214,18 +214,18 @@ RemoteGDB::getregs() gdbregs.regs[KGDB_REG_PC] = context->readPC(); // @todo: Currently this is very Alpha specific. - if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) { - for (int i = 0; i < AlphaISA::NumIntArchRegs; ++i) { - gdbregs.regs[i] = context->readIntReg(AlphaISA::reg_redir[i]); + if (PcPAL(gdbregs.regs[KGDB_REG_PC])) { + for (int i = 0; i < NumIntArchRegs; ++i) { + gdbregs.regs[i] = context->readIntReg(reg_redir[i]); } } else { - for (int i = 0; i < AlphaISA::NumIntArchRegs; ++i) { + for (int i = 0; i < NumIntArchRegs; ++i) { gdbregs.regs[i] = context->readIntReg(i); } } #ifdef KGDB_FP_REGS - for (int i = 0; i < AlphaISA::NumFloatArchRegs; ++i) { + for (int i = 0; i < NumFloatArchRegs; ++i) { gdbregs.regs[i + KGDB_REG_F0] = context->readFloatRegBits(i); } #endif @@ -241,18 +241,18 @@ void RemoteGDB::setregs() { // @todo: Currently this is very Alpha specific. - if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) { - for (int i = 0; i < AlphaISA::NumIntArchRegs; ++i) { - context->setIntReg(AlphaISA::reg_redir[i], gdbregs.regs[i]); + if (PcPAL(gdbregs.regs[KGDB_REG_PC])) { + for (int i = 0; i < NumIntArchRegs; ++i) { + context->setIntReg(reg_redir[i], gdbregs.regs[i]); } } else { - for (int i = 0; i < AlphaISA::NumIntArchRegs; ++i) { + for (int i = 0; i < NumIntArchRegs; ++i) { context->setIntReg(i, gdbregs.regs[i]); } } #ifdef KGDB_FP_REGS - for (int i = 0; i < AlphaISA::NumFloatArchRegs; ++i) { + for (int i = 0; i < NumFloatArchRegs; ++i) { context->setFloatRegBits(i, gdbregs.regs[i + KGDB_REG_F0]); } #endif diff --git a/src/arch/alpha/stacktrace.cc b/src/arch/alpha/stacktrace.cc index b2fa89cb8..a29a4eb4d 100644 --- a/src/arch/alpha/stacktrace.cc +++ b/src/arch/alpha/stacktrace.cc @@ -142,7 +142,7 @@ namespace AlphaISA { tc = _tc; - bool usermode = (tc->readMiscRegNoEffect(AlphaISA::IPR_DTB_CM) & 0x18) != 0; + bool usermode = (tc->readMiscRegNoEffect(IPR_DTB_CM) & 0x18) != 0; Addr pc = tc->readNextPC(); bool kernel = tc->getSystemPtr()->kernelStart <= pc && @@ -159,7 +159,7 @@ namespace AlphaISA } SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; - Addr ksp = tc->readIntReg(AlphaISA::StackPointerReg); + Addr ksp = tc->readIntReg(StackPointerReg); Addr bottom = ksp & ~0x3fff; Addr addr; @@ -215,22 +215,22 @@ namespace AlphaISA bool StackTrace::isEntry(Addr addr) { - if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp12)) + if (addr == tc->readMiscRegNoEffect(IPR_PALtemp12)) return true; - if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp7)) + if (addr == tc->readMiscRegNoEffect(IPR_PALtemp7)) return true; - if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp11)) + if (addr == tc->readMiscRegNoEffect(IPR_PALtemp11)) return true; - if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp21)) + if (addr == tc->readMiscRegNoEffect(IPR_PALtemp21)) return true; - if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp9)) + if (addr == tc->readMiscRegNoEffect(IPR_PALtemp9)) return true; - if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp2)) + if (addr == tc->readMiscRegNoEffect(IPR_PALtemp2)) return true; return false; diff --git a/src/arch/alpha/stacktrace.hh b/src/arch/alpha/stacktrace.hh index c028afe2b..39fd3d286 100644 --- a/src/arch/alpha/stacktrace.hh +++ b/src/arch/alpha/stacktrace.hh @@ -61,8 +61,6 @@ namespace AlphaISA class StackTrace { - protected: - typedef AlphaISA::MachInst MachInst; private: ThreadContext *tc; std::vector stack; diff --git a/src/arch/alpha/system.cc b/src/arch/alpha/system.cc index 63efef4a0..6bff3d798 100644 --- a/src/arch/alpha/system.cc +++ b/src/arch/alpha/system.cc @@ -42,8 +42,7 @@ #include "params/AlphaSystem.hh" #include "sim/byteswap.hh" - -using namespace LittleEndianGuest; +using namespace AlphaISA; AlphaSystem::AlphaSystem(Params *p) : System(p) @@ -67,8 +66,8 @@ AlphaSystem::AlphaSystem(Params *p) // Load program sections into memory - pal->loadSections(&functionalPort, AlphaISA::LoadAddrMask); - console->loadSections(&functionalPort, AlphaISA::LoadAddrMask); + pal->loadSections(&functionalPort, LoadAddrMask); + console->loadSections(&functionalPort, LoadAddrMask); // load symbols if (!console->loadGlobalSymbols(consoleSymtab)) @@ -172,11 +171,11 @@ AlphaSystem::fixFuncEventAddr(Addr addr) const uint32_t gp_lda_pattern = (8 << 26) | (29 << 21) | (29 << 16); uint32_t i1 = virtPort.read(addr); - uint32_t i2 = virtPort.read(addr + sizeof(AlphaISA::MachInst)); + uint32_t i2 = virtPort.read(addr + sizeof(MachInst)); if ((i1 & inst_mask) == gp_ldah_pattern && (i2 & inst_mask) == gp_lda_pattern) { - Addr new_addr = addr + 2* sizeof(AlphaISA::MachInst); + Addr new_addr = addr + 2* sizeof(MachInst); DPRINTF(Loader, "fixFuncEventAddr: %p -> %p", addr, new_addr); return new_addr; } else { @@ -190,7 +189,7 @@ AlphaSystem::setAlphaAccess(Addr access) { Addr addr = 0; if (consoleSymtab->findAddress("m5AlphaAccess", addr)) { - virtPort.write(addr, htog(AlphaISA::Phys2K0Seg(access))); + virtPort.write(addr, htog(Phys2K0Seg(access))); } else panic("could not find m5AlphaAccess\n"); } diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc index 2694cf38f..5e231d4d8 100644 --- a/src/arch/alpha/tlb.cc +++ b/src/arch/alpha/tlb.cc @@ -622,7 +622,7 @@ TLB::index(bool advance) return *entry; } -/* end namespace AlphaISA */ } +} // namespace AlphaISA AlphaISA::ITB * AlphaITBParams::create() diff --git a/src/arch/alpha/tlb.hh b/src/arch/alpha/tlb.hh index 98f845e21..f127d09a7 100644 --- a/src/arch/alpha/tlb.hh +++ b/src/arch/alpha/tlb.hh @@ -88,8 +88,8 @@ namespace AlphaISA // static helper functions... really EV5 VM traits static bool validVirtualAddress(Addr vaddr) { // unimplemented bits must be all 0 or all 1 - Addr unimplBits = vaddr & AlphaISA::VAddrUnImplMask; - return (unimplBits == 0) || (unimplBits == AlphaISA::VAddrUnImplMask); + Addr unimplBits = vaddr & VAddrUnImplMask; + return (unimplBits == 0) || (unimplBits == VAddrUnImplMask); } static Fault checkCacheability(RequestPtr &req, bool itb = false); diff --git a/src/arch/alpha/utility.hh b/src/arch/alpha/utility.hh index 43d4908b4..220aa6695 100644 --- a/src/arch/alpha/utility.hh +++ b/src/arch/alpha/utility.hh @@ -46,7 +46,7 @@ namespace AlphaISA inline bool inUserMode(ThreadContext *tc) { - return (tc->readMiscRegNoEffect(AlphaISA::IPR_DTB_CM) & 0x18) != 0; + return (tc->readMiscRegNoEffect(IPR_DTB_CM) & 0x18) != 0; } inline bool diff --git a/src/arch/alpha/vtophys.cc b/src/arch/alpha/vtophys.cc index 439af3bd7..88e5a3090 100644 --- a/src/arch/alpha/vtophys.cc +++ b/src/arch/alpha/vtophys.cc @@ -40,27 +40,28 @@ #include "mem/vport.hh" using namespace std; -using namespace AlphaISA; -AlphaISA::PageTableEntry -AlphaISA::kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr) +namespace AlphaISA { + +PageTableEntry +kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, VAddr vaddr) { Addr level1_pte = ptbr + vaddr.level1(); - AlphaISA::PageTableEntry level1 = mem->read(level1_pte); + PageTableEntry level1 = mem->read(level1_pte); if (!level1.valid()) { DPRINTF(VtoPhys, "level 1 PTE not valid, va = %#\n", vaddr); return 0; } Addr level2_pte = level1.paddr() + vaddr.level2(); - AlphaISA::PageTableEntry level2 = mem->read(level2_pte); + PageTableEntry level2 = mem->read(level2_pte); if (!level2.valid()) { DPRINTF(VtoPhys, "level 2 PTE not valid, va = %#x\n", vaddr); return 0; } Addr level3_pte = level2.paddr() + vaddr.level3(); - AlphaISA::PageTableEntry level3 = mem->read(level3_pte); + PageTableEntry level3 = mem->read(level3_pte); if (!level3.valid()) { DPRINTF(VtoPhys, "level 3 PTE not valid, va = %#x\n", vaddr); return 0; @@ -69,13 +70,13 @@ AlphaISA::kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vadd } Addr -AlphaISA::vtophys(Addr vaddr) +vtophys(Addr vaddr) { Addr paddr = 0; - if (AlphaISA::IsUSeg(vaddr)) + if (IsUSeg(vaddr)) DPRINTF(VtoPhys, "vtophys: invalid vaddr %#x", vaddr); - else if (AlphaISA::IsK0Seg(vaddr)) - paddr = AlphaISA::K0Seg2Phys(vaddr); + else if (IsK0Seg(vaddr)) + paddr = K0Seg2Phys(vaddr); else panic("vtophys: ptbr is not set on virtual lookup"); @@ -85,22 +86,22 @@ AlphaISA::vtophys(Addr vaddr) } Addr -AlphaISA::vtophys(ThreadContext *tc, Addr addr) +vtophys(ThreadContext *tc, Addr addr) { - AlphaISA::VAddr vaddr = addr; - Addr ptbr = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp20); + VAddr vaddr = addr; + Addr ptbr = tc->readMiscRegNoEffect(IPR_PALtemp20); Addr paddr = 0; //@todo Andrew couldn't remember why he commented some of this code //so I put it back in. Perhaps something to do with gdb debugging? - if (AlphaISA::PcPAL(vaddr) && (vaddr < AlphaISA::PalMax)) { + if (PcPAL(vaddr) && (vaddr < PalMax)) { paddr = vaddr & ~ULL(1); } else { - if (AlphaISA::IsK0Seg(vaddr)) { - paddr = AlphaISA::K0Seg2Phys(vaddr); + if (IsK0Seg(vaddr)) { + paddr = K0Seg2Phys(vaddr); } else if (!ptbr) { paddr = vaddr; } else { - AlphaISA::PageTableEntry pte = + PageTableEntry pte = kernel_pte_lookup(tc->getPhysPort(), ptbr, vaddr); if (pte.valid()) paddr = pte.paddr() | vaddr.offset(); @@ -113,3 +114,5 @@ AlphaISA::vtophys(ThreadContext *tc, Addr addr) return paddr; } +} // namespace AlphaISA + diff --git a/src/arch/alpha/vtophys.hh b/src/arch/alpha/vtophys.hh index bd2ee8468..9cce85d6c 100644 --- a/src/arch/alpha/vtophys.hh +++ b/src/arch/alpha/vtophys.hh @@ -42,7 +42,7 @@ class FunctionalPort; namespace AlphaISA { PageTableEntry - kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr); + kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, VAddr vaddr); Addr vtophys(Addr vaddr); Addr vtophys(ThreadContext *tc, Addr vaddr); -- cgit v1.2.3 From cf7ddd8e8ac92cf5b90cd89a028414dd782c645a Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 27 Sep 2008 21:03:48 -0700 Subject: style: Make a style pass over the whole arch/alpha directory. --- src/arch/alpha/ev5.cc | 11 +- src/arch/alpha/ev5.hh | 4 +- src/arch/alpha/faults.cc | 40 +-- src/arch/alpha/faults.hh | 59 +++-- src/arch/alpha/floatregfile.cc | 28 +- src/arch/alpha/floatregfile.hh | 45 ++-- src/arch/alpha/freebsd/system.cc | 3 - src/arch/alpha/freebsd/system.hh | 1 - src/arch/alpha/idle_event.cc | 7 +- src/arch/alpha/intregfile.cc | 53 ++-- src/arch/alpha/intregfile.hh | 63 ++--- src/arch/alpha/ipr.cc | 210 +++++++-------- src/arch/alpha/ipr.hh | 402 ++++++++++++++--------------- src/arch/alpha/isa_traits.hh | 257 +++++++++---------- src/arch/alpha/linux/linux.cc | 9 +- src/arch/alpha/linux/linux.hh | 20 +- src/arch/alpha/linux/process.cc | 2 - src/arch/alpha/linux/process.hh | 1 + src/arch/alpha/linux/system.cc | 2 - src/arch/alpha/linux/system.hh | 7 +- src/arch/alpha/linux/threadinfo.hh | 2 +- src/arch/alpha/locked_mem.hh | 6 +- src/arch/alpha/miscregfile.cc | 206 ++++++++------- src/arch/alpha/miscregfile.hh | 120 ++++----- src/arch/alpha/mmaped_ipr.hh | 5 +- src/arch/alpha/osfpal.cc | 10 +- src/arch/alpha/osfpal.hh | 6 +- src/arch/alpha/pagetable.cc | 55 ++-- src/arch/alpha/pagetable.hh | 181 ++++++------- src/arch/alpha/predecoder.hh | 114 ++++---- src/arch/alpha/process.cc | 6 +- src/arch/alpha/process.hh | 12 +- src/arch/alpha/regfile.cc | 101 ++++---- src/arch/alpha/regfile.hh | 273 +++++++++++--------- src/arch/alpha/remote_gdb.cc | 49 ++-- src/arch/alpha/remote_gdb.hh | 40 ++- src/arch/alpha/stacktrace.cc | 514 ++++++++++++++++++------------------- src/arch/alpha/stacktrace.hh | 126 ++++----- src/arch/alpha/syscallreturn.hh | 35 +-- src/arch/alpha/system.cc | 8 +- src/arch/alpha/system.hh | 16 +- src/arch/alpha/tlb.cc | 61 +++-- src/arch/alpha/tlb.hh | 208 +++++++-------- src/arch/alpha/tru64/process.cc | 25 +- src/arch/alpha/tru64/process.hh | 9 +- src/arch/alpha/tru64/tru64.hh | 23 +- src/arch/alpha/types.hh | 67 ++--- src/arch/alpha/utility.cc | 8 +- src/arch/alpha/utility.hh | 244 +++++++++--------- src/arch/alpha/vtophys.cc | 1 - src/arch/alpha/vtophys.hh | 11 +- 51 files changed, 1910 insertions(+), 1856 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index 166d42bc6..7dc02a611 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -459,8 +459,7 @@ MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) // really a control write ipr[idx] = val; - tc->getDTBPtr()->flushAddr(val, - DTB_ASN_ASN(ipr[IPR_DTB_ASN])); + tc->getDTBPtr()->flushAddr(val, DTB_ASN_ASN(ipr[IPR_DTB_ASN])); break; case IPR_DTB_TAG: { @@ -529,8 +528,7 @@ MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) // really a control write ipr[idx] = val; - tc->getITBPtr()->flushAddr(val, - ITB_ASN_ASN(ipr[IPR_ITB_ASN])); + tc->getITBPtr()->flushAddr(val, ITB_ASN_ASN(ipr[IPR_ITB_ASN])); break; default: @@ -541,18 +539,17 @@ MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) // no error... } - void copyIprs(ThreadContext *src, ThreadContext *dest) { - for (int i = 0; i < NumInternalProcRegs; ++i) { + for (int i = 0; i < NumInternalProcRegs; ++i) dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i)); - } } } // namespace AlphaISA #if FULL_SYSTEM + using namespace AlphaISA; Fault diff --git a/src/arch/alpha/ev5.hh b/src/arch/alpha/ev5.hh index a40ca6749..4c4f282f1 100644 --- a/src/arch/alpha/ev5.hh +++ b/src/arch/alpha/ev5.hh @@ -65,7 +65,9 @@ const Addr PAddrUncachedBit39 = ULL(0x8000000000); const Addr PAddrUncachedBit40 = ULL(0x10000000000); const Addr PAddrUncachedBit43 = ULL(0x80000000000); const Addr PAddrUncachedMask = ULL(0x807ffffffff); // Clear PA<42:35> -inline Addr Phys2K0Seg(Addr addr) + +inline Addr +Phys2K0Seg(Addr addr) { #if !ALPHA_TLASER if (addr & PAddrUncachedBit43) { diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc index 845ac0288..dae188839 100644 --- a/src/arch/alpha/faults.cc +++ b/src/arch/alpha/faults.cc @@ -40,8 +40,7 @@ #include "mem/page_table.hh" #endif -namespace AlphaISA -{ +namespace AlphaISA { FaultName MachineCheckFault::_name = "mchk"; FaultVect MachineCheckFault::_vect = 0x0401; @@ -109,7 +108,8 @@ FaultStat IntegerOverflowFault::_count; #if FULL_SYSTEM -void AlphaFault::invoke(ThreadContext * tc) +void +AlphaFault::invoke(ThreadContext *tc) { FaultBase::invoke(tc); countStat()++; @@ -128,29 +128,31 @@ void AlphaFault::invoke(ThreadContext * tc) tc->setNextPC(tc->readPC() + sizeof(MachInst)); } -void ArithmeticFault::invoke(ThreadContext * tc) +void +ArithmeticFault::invoke(ThreadContext *tc) { FaultBase::invoke(tc); panic("Arithmetic traps are unimplemented!"); } -void DtbFault::invoke(ThreadContext * tc) +void +DtbFault::invoke(ThreadContext *tc) { // Set fault address and flags. Even though we're modeling an // EV5, we use the EV6 technique of not latching fault registers // on VPTE loads (instead of locking the registers until IPR_VA is // read, like the EV5). The EV6 approach is cleaner and seems to // work with EV5 PAL code, but not the other way around. - if (!tc->misspeculating() - && !(reqFlags & VPTE) && !(reqFlags & NO_FAULT)) { + if (!tc->misspeculating() && + !(reqFlags & VPTE) && !(reqFlags & NO_FAULT)) { // set VA register with faulting address tc->setMiscRegNoEffect(IPR_VA, vaddr); // set MM_STAT register flags tc->setMiscRegNoEffect(IPR_MM_STAT, - (((Opcode(tc->getInst()) & 0x3f) << 11) - | ((Ra(tc->getInst()) & 0x1f) << 6) - | (flags & 0x3f))); + (((Opcode(tc->getInst()) & 0x3f) << 11) | + ((Ra(tc->getInst()) & 0x1f) << 6) | + (flags & 0x3f))); // set VA_FORM register with faulting formatted address tc->setMiscRegNoEffect(IPR_VA_FORM, @@ -160,13 +162,13 @@ void DtbFault::invoke(ThreadContext * tc) AlphaFault::invoke(tc); } -void ItbFault::invoke(ThreadContext * tc) +void +ItbFault::invoke(ThreadContext *tc) { if (!tc->misspeculating()) { tc->setMiscRegNoEffect(IPR_ITB_TAG, pc); tc->setMiscRegNoEffect(IPR_IFAULT_VA_FORM, - tc->readMiscRegNoEffect(IPR_IVPTBR) | - (VAddr(pc).vpn() << 3)); + tc->readMiscRegNoEffect(IPR_IVPTBR) | (VAddr(pc).vpn() << 3)); } AlphaFault::invoke(tc); @@ -174,12 +176,13 @@ void ItbFault::invoke(ThreadContext * tc) #else -void ItbPageFault::invoke(ThreadContext * tc) +void +ItbPageFault::invoke(ThreadContext *tc) { Process *p = tc->getProcessPtr(); TlbEntry entry; bool success = p->pTable->lookup(pc, entry); - if(!success) { + if (!success) { panic("Tried to execute unmapped address %#x.\n", pc); } else { VAddr vaddr(pc); @@ -187,16 +190,17 @@ void ItbPageFault::invoke(ThreadContext * tc) } } -void NDtbMissFault::invoke(ThreadContext * tc) +void +NDtbMissFault::invoke(ThreadContext *tc) { Process *p = tc->getProcessPtr(); TlbEntry entry; bool success = p->pTable->lookup(vaddr, entry); - if(!success) { + if (!success) { p->checkAndAllocNextPage(vaddr); success = p->pTable->lookup(vaddr, entry); } - if(!success) { + if (!success) { panic("Tried to access unmapped address %#x.\n", (Addr)vaddr); } else { tc->getDTBPtr()->insert(vaddr.page(), entry); diff --git a/src/arch/alpha/faults.hh b/src/arch/alpha/faults.hh index 1d2ac593a..4b107273b 100644 --- a/src/arch/alpha/faults.hh +++ b/src/arch/alpha/faults.hh @@ -29,18 +29,16 @@ * Kevin Lim */ -#ifndef __ALPHA_FAULTS_HH__ -#define __ALPHA_FAULTS_HH__ +#ifndef __ARCH_ALPHA_FAULTS_HH__ +#define __ARCH_ALPHA_FAULTS_HH__ +#include "arch/alpha/pagetable.hh" #include "config/full_system.hh" #include "sim/faults.hh" -#include "arch/alpha/pagetable.hh" - // The design of the "name" and "vect" functions is in sim/faults.hh -namespace AlphaISA -{ +namespace AlphaISA { typedef const Addr FaultVect; @@ -63,6 +61,7 @@ class MachineCheckFault : public AlphaFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: FaultName name() const {return _name;} FaultVect vect() {return _vect;} @@ -76,6 +75,7 @@ class AlignmentFault : public AlphaFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: FaultName name() const {return _name;} FaultVect vect() {return _vect;} @@ -94,6 +94,7 @@ class ResetFault : public AlphaFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: FaultName name() const {return _name;} FaultVect vect() {return _vect;} @@ -102,12 +103,14 @@ class ResetFault : public AlphaFault class ArithmeticFault : public AlphaFault { - protected: - bool skipFaultingInstruction() {return true;} private: static FaultName _name; static FaultVect _vect; static FaultStat _count; + + protected: + bool skipFaultingInstruction() {return true;} + public: FaultName name() const {return _name;} FaultVect vect() {return _vect;} @@ -119,12 +122,14 @@ class ArithmeticFault : public AlphaFault class InterruptFault : public AlphaFault { - protected: - bool setRestartAddress() {return false;} private: static FaultName _name; static FaultVect _vect; static FaultStat _count; + + protected: + bool setRestartAddress() {return false;} + public: FaultName name() const {return _name;} FaultVect vect() {return _vect;} @@ -137,6 +142,7 @@ class DtbFault : public AlphaFault VAddr vaddr; uint32_t reqFlags; uint64_t flags; + public: DtbFault(VAddr _vaddr, uint32_t _reqFlags, uint64_t _flags) : vaddr(_vaddr), reqFlags(_reqFlags), flags(_flags) @@ -155,6 +161,7 @@ class NDtbMissFault : public DtbFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: NDtbMissFault(VAddr vaddr, uint32_t reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) @@ -173,6 +180,7 @@ class PDtbMissFault : public DtbFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: PDtbMissFault(VAddr vaddr, uint32_t reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) @@ -188,6 +196,7 @@ class DtbPageFault : public DtbFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: DtbPageFault(VAddr vaddr, uint32_t reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) @@ -203,6 +212,7 @@ class DtbAcvFault : public DtbFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: DtbAcvFault(VAddr vaddr, uint32_t reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) @@ -218,6 +228,7 @@ class DtbAlignmentFault : public DtbFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: DtbAlignmentFault(VAddr vaddr, uint32_t reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) @@ -231,10 +242,9 @@ class ItbFault : public AlphaFault { protected: Addr pc; + public: - ItbFault(Addr _pc) - : pc(_pc) - { } + ItbFault(Addr _pc) : pc(_pc) { } FaultName name() const = 0; FaultVect vect() = 0; FaultStat & countStat() = 0; @@ -249,10 +259,9 @@ class ItbPageFault : public ItbFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: - ItbPageFault(Addr pc) - : ItbFault(pc) - { } + ItbPageFault(Addr pc) : ItbFault(pc) { } FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} @@ -267,10 +276,9 @@ class ItbAcvFault : public ItbFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: - ItbAcvFault(Addr pc) - : ItbFault(pc) - { } + ItbAcvFault(Addr pc) : ItbFault(pc) { } FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} @@ -282,6 +290,7 @@ class UnimplementedOpcodeFault : public AlphaFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: FaultName name() const {return _name;} FaultVect vect() {return _vect;} @@ -294,6 +303,7 @@ class FloatEnableFault : public AlphaFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: FaultName name() const {return _name;} FaultVect vect() {return _vect;} @@ -302,12 +312,14 @@ class FloatEnableFault : public AlphaFault class PalFault : public AlphaFault { - protected: - bool skipFaultingInstruction() {return true;} private: static FaultName _name; static FaultVect _vect; static FaultStat _count; + + protected: + bool skipFaultingInstruction() {return true;} + public: FaultName name() const {return _name;} FaultVect vect() {return _vect;} @@ -320,12 +332,13 @@ class IntegerOverflowFault : public AlphaFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; -} // AlphaISA namespace +} // namespace AlphaISA -#endif // __FAULTS_HH__ +#endif // __ARCH_ALPHA_FAULTS_HH__ diff --git a/src/arch/alpha/floatregfile.cc b/src/arch/alpha/floatregfile.cc index 512b0df95..15dc13166 100644 --- a/src/arch/alpha/floatregfile.cc +++ b/src/arch/alpha/floatregfile.cc @@ -33,17 +33,23 @@ #include "arch/alpha/floatregfile.hh" #include "sim/serialize.hh" -namespace AlphaISA +namespace AlphaISA { +void +FloatRegFile::clear() { - void - FloatRegFile::serialize(std::ostream &os) - { - SERIALIZE_ARRAY(q, NumFloatRegs); - } + std::memset(d, 0, sizeof(d)); +} + +void +FloatRegFile::serialize(std::ostream &os) +{ + SERIALIZE_ARRAY(q, NumFloatRegs); +} - void - FloatRegFile::unserialize(Checkpoint *cp, const std::string §ion) - { - UNSERIALIZE_ARRAY(q, NumFloatRegs); - } +void +FloatRegFile::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_ARRAY(q, NumFloatRegs); } + +} // namespace AlphaISA diff --git a/src/arch/alpha/floatregfile.hh b/src/arch/alpha/floatregfile.hh index e69e8d186..82592d80d 100644 --- a/src/arch/alpha/floatregfile.hh +++ b/src/arch/alpha/floatregfile.hh @@ -32,37 +32,36 @@ #ifndef __ARCH_ALPHA_FLOATREGFILE_HH__ #define __ARCH_ALPHA_FLOATREGFILE_HH__ +#include +#include + #include "arch/alpha/isa_traits.hh" #include "arch/alpha/types.hh" -#include -#include - class Checkpoint; -namespace AlphaISA -{ - static inline std::string getFloatRegName(RegIndex) - { - return ""; - } +namespace AlphaISA { - class FloatRegFile - { - public: +static inline std::string +getFloatRegName(RegIndex) +{ + return ""; +} - union { - uint64_t q[NumFloatRegs]; // integer qword view - double d[NumFloatRegs]; // double-precision floating point view - }; +class FloatRegFile +{ + public: + union { + uint64_t q[NumFloatRegs]; // integer qword view + double d[NumFloatRegs]; // double-precision floating point view + }; - void serialize(std::ostream &os); + void clear(); - void unserialize(Checkpoint *cp, const std::string §ion); + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); +}; - void clear() - { std::memset(d, 0, sizeof(d)); } - }; -} +} // namespace AlphaISA -#endif +#endif // __ARCH_ALPHA_FLOATREGFILE_HH__ diff --git a/src/arch/alpha/freebsd/system.cc b/src/arch/alpha/freebsd/system.cc index f666de604..f2ea1b587 100644 --- a/src/arch/alpha/freebsd/system.cc +++ b/src/arch/alpha/freebsd/system.cc @@ -62,14 +62,12 @@ FreebsdAlphaSystem::FreebsdAlphaSystem(Params *p) addKernelFuncEvent("calibrate_clocks"); } - FreebsdAlphaSystem::~FreebsdAlphaSystem() { delete skipDelayEvent; delete skipCalibrateClocks; } - void FreebsdAlphaSystem::doCalibrateClocks(ThreadContext *tc) { @@ -84,7 +82,6 @@ FreebsdAlphaSystem::doCalibrateClocks(ThreadContext *tc) virtPort.write(timer_vaddr, (uint32_t)TIMER_FREQUENCY); } - void FreebsdAlphaSystem::SkipCalibrateClocksEvent::process(ThreadContext *tc) { diff --git a/src/arch/alpha/freebsd/system.hh b/src/arch/alpha/freebsd/system.hh index 8e8493f97..48f6238c0 100644 --- a/src/arch/alpha/freebsd/system.hh +++ b/src/arch/alpha/freebsd/system.hh @@ -57,7 +57,6 @@ class FreebsdAlphaSystem : public AlphaSystem ~FreebsdAlphaSystem(); void doCalibrateClocks(ThreadContext *tc); - }; #endif // __ARCH_ALPHA_FREEBSD_SYSTEM_HH__ diff --git a/src/arch/alpha/idle_event.cc b/src/arch/alpha/idle_event.cc index 337166aec..bb68782e7 100644 --- a/src/arch/alpha/idle_event.cc +++ b/src/arch/alpha/idle_event.cc @@ -38,8 +38,9 @@ using namespace AlphaISA; void IdleStartEvent::process(ThreadContext *tc) { - if (tc->getKernelStats()) - tc->getKernelStats()->setIdleProcess( - tc->readMiscRegNoEffect(IPR_PALtemp23), tc); + if (tc->getKernelStats()) { + MiscReg val = tc->readMiscRegNoEffect(IPR_PALtemp23); + tc->getKernelStats()->setIdleProcess(val, tc); + } remove(); } diff --git a/src/arch/alpha/intregfile.cc b/src/arch/alpha/intregfile.cc index d1dfc5168..8f692f856 100644 --- a/src/arch/alpha/intregfile.cc +++ b/src/arch/alpha/intregfile.cc @@ -30,36 +30,45 @@ * Kevin Lim */ +#include + #include "arch/alpha/isa_traits.hh" #include "arch/alpha/intregfile.hh" #include "sim/serialize.hh" -namespace AlphaISA -{ +namespace AlphaISA { + #if FULL_SYSTEM - const int reg_redir[NumIntRegs] = { - /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, - /* 8 */ 32, 33, 34, 35, 36, 37, 38, 15, - /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23, - /* 24 */ 24, 39, 26, 27, 28, 29, 30, 31 }; +const int reg_redir[NumIntRegs] = { + /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, + /* 8 */ 32, 33, 34, 35, 36, 37, 38, 15, + /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23, + /* 24 */ 24, 39, 26, 27, 28, 29, 30, 31 }; #else - const int reg_redir[NumIntRegs] = { - /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, - /* 8 */ 8, 9, 10, 11, 12, 13, 14, 15, - /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23, - /* 24 */ 24, 25, 26, 27, 28, 29, 30, 31 }; +const int reg_redir[NumIntRegs] = { + /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, + /* 8 */ 8, 9, 10, 11, 12, 13, 14, 15, + /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23, + /* 24 */ 24, 25, 26, 27, 28, 29, 30, 31 }; #endif - void - IntRegFile::serialize(std::ostream &os) - { - SERIALIZE_ARRAY(regs, NumIntRegs); - } +void +IntRegFile::clear() +{ + std::memset(regs, 0, sizeof(regs)); +} + +void +IntRegFile::serialize(std::ostream &os) +{ + SERIALIZE_ARRAY(regs, NumIntRegs); +} - void - IntRegFile::unserialize(Checkpoint *cp, const std::string §ion) - { - UNSERIALIZE_ARRAY(regs, NumIntRegs); - } +void +IntRegFile::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_ARRAY(regs, NumIntRegs); } +} // namespace AlphaISA + diff --git a/src/arch/alpha/intregfile.hh b/src/arch/alpha/intregfile.hh index dea160992..f6ba72e79 100644 --- a/src/arch/alpha/intregfile.hh +++ b/src/arch/alpha/intregfile.hh @@ -32,47 +32,48 @@ #ifndef __ARCH_ALPHA_INTREGFILE_HH__ #define __ARCH_ALPHA_INTREGFILE_HH__ -#include "arch/alpha/types.hh" +#include +#include -#include -#include +#include "arch/alpha/types.hh" class Checkpoint; -namespace AlphaISA -{ - static inline std::string getIntRegName(RegIndex) - { - return ""; - } +namespace AlphaISA { - // redirected register map, really only used for the full system case. - extern const int reg_redir[NumIntRegs]; +static inline std::string +getIntRegName(RegIndex) +{ + return ""; +} - class IntRegFile - { - protected: - IntReg regs[NumIntRegs]; +// redirected register map, really only used for the full system case. +extern const int reg_redir[NumIntRegs]; - public: +class IntRegFile +{ + protected: + IntReg regs[NumIntRegs]; - IntReg readReg(int intReg) - { - return regs[intReg]; - } + public: + IntReg + readReg(int intReg) + { + return regs[intReg]; + } - void setReg(int intReg, const IntReg &val) - { - regs[intReg] = val; - } + void + setReg(int intReg, const IntReg &val) + { + regs[intReg] = val; + } - void serialize(std::ostream &os); + void clear(); - void unserialize(Checkpoint *cp, const std::string §ion); + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); +}; - void clear() - { std::memset(regs, 0, sizeof(regs)); } - }; -} +} // namespace AlphaISA -#endif +#endif // __ARCH_ALPHA_INTREGFILE_HH__ diff --git a/src/arch/alpha/ipr.cc b/src/arch/alpha/ipr.cc index a76fcc2bc..502ada5eb 100644 --- a/src/arch/alpha/ipr.cc +++ b/src/arch/alpha/ipr.cc @@ -28,113 +28,115 @@ * Authors: Gabe Black */ -#include -#include +#include +#include #include "arch/alpha/ipr.hh" -namespace AlphaISA +namespace AlphaISA { + +md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs] = { + + //Write only + RAW_IPR_HWINT_CLR, // H/W interrupt clear register + RAW_IPR_SL_XMIT, // serial line transmit register + RAW_IPR_DC_FLUSH, + RAW_IPR_IC_FLUSH, // instruction cache flush control + RAW_IPR_ALT_MODE, // alternate mode register + RAW_IPR_DTB_IA, // DTLB invalidate all register + RAW_IPR_DTB_IAP, // DTLB invalidate all process register + RAW_IPR_ITB_IA, // ITLB invalidate all register + RAW_IPR_ITB_IAP, // ITLB invalidate all process register + + //Read only + RAW_IPR_INTID, // interrupt ID register + RAW_IPR_SL_RCV, // serial line receive register + RAW_IPR_MM_STAT, // data MMU fault status register + RAW_IPR_ITB_PTE_TEMP, // ITLB page table entry temp register + RAW_IPR_DTB_PTE_TEMP, // DTLB page table entry temporary register + + RAW_IPR_ISR, // interrupt summary register + RAW_IPR_ITB_TAG, // ITLB tag register + RAW_IPR_ITB_PTE, // ITLB page table entry register + RAW_IPR_ITB_ASN, // ITLB address space register + RAW_IPR_ITB_IS, // ITLB invalidate select register + RAW_IPR_SIRR, // software interrupt request register + RAW_IPR_ASTRR, // asynchronous system trap request register + RAW_IPR_ASTER, // asynchronous system trap enable register + RAW_IPR_EXC_ADDR, // exception address register + RAW_IPR_EXC_SUM, // exception summary register + RAW_IPR_EXC_MASK, // exception mask register + RAW_IPR_PAL_BASE, // PAL base address register + RAW_IPR_ICM, // instruction current mode + RAW_IPR_IPLR, // interrupt priority level register + RAW_IPR_IFAULT_VA_FORM, // formatted faulting virtual addr register + RAW_IPR_IVPTBR, // virtual page table base register + RAW_IPR_ICSR, // instruction control and status register + RAW_IPR_IC_PERR_STAT, // inst cache parity error status register + RAW_IPR_PMCTR, // performance counter register + + // PAL temporary registers... + // register meanings gleaned from osfpal.s source code + RAW_IPR_PALtemp0, // local scratch + RAW_IPR_PALtemp1, // local scratch + RAW_IPR_PALtemp2, // entUna + RAW_IPR_PALtemp3, // CPU specific impure area pointer + RAW_IPR_PALtemp4, // memory management temp + RAW_IPR_PALtemp5, // memory management temp + RAW_IPR_PALtemp6, // memory management temp + RAW_IPR_PALtemp7, // entIF + RAW_IPR_PALtemp8, // intmask + RAW_IPR_PALtemp9, // entSys + RAW_IPR_PALtemp10, // ?? + RAW_IPR_PALtemp11, // entInt + RAW_IPR_PALtemp12, // entArith + RAW_IPR_PALtemp13, // reserved for platform specific PAL + RAW_IPR_PALtemp14, // reserved for platform specific PAL + RAW_IPR_PALtemp15, // reserved for platform specific PAL + RAW_IPR_PALtemp16, // scratch / whami<7:0> / mces<4:0> + RAW_IPR_PALtemp17, // sysval + RAW_IPR_PALtemp18, // usp + RAW_IPR_PALtemp19, // ksp + RAW_IPR_PALtemp20, // PTBR + RAW_IPR_PALtemp21, // entMM + RAW_IPR_PALtemp22, // kgp + RAW_IPR_PALtemp23, // PCBB + + RAW_IPR_DTB_ASN, // DTLB address space number register + RAW_IPR_DTB_CM, // DTLB current mode register + RAW_IPR_DTB_TAG, // DTLB tag register + RAW_IPR_DTB_PTE, // DTLB page table entry register + + RAW_IPR_VA, // fault virtual address register + RAW_IPR_VA_FORM, // formatted virtual address register + RAW_IPR_MVPTBR, // MTU virtual page table base register + RAW_IPR_DTB_IS, // DTLB invalidate single register + RAW_IPR_CC, // cycle counter register + RAW_IPR_CC_CTL, // cycle counter control register + RAW_IPR_MCSR, // MTU control register + + RAW_IPR_DC_PERR_STAT, // Dcache parity error status register + RAW_IPR_DC_TEST_CTL, // Dcache test tag control register + RAW_IPR_DC_TEST_TAG, // Dcache test tag register + RAW_IPR_DC_TEST_TAG_TEMP, // Dcache test tag temporary register + RAW_IPR_DC_MODE, // Dcache mode register + RAW_IPR_MAF_MODE // miss address file mode register +}; + +int IprToMiscRegIndex[MaxInternalProcRegs]; + +void +initializeIprTable() { - md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs] = - { - //Write only - RAW_IPR_HWINT_CLR, // H/W interrupt clear register - RAW_IPR_SL_XMIT, // serial line transmit register - RAW_IPR_DC_FLUSH, - RAW_IPR_IC_FLUSH, // instruction cache flush control - RAW_IPR_ALT_MODE, // alternate mode register - RAW_IPR_DTB_IA, // DTLB invalidate all register - RAW_IPR_DTB_IAP, // DTLB invalidate all process register - RAW_IPR_ITB_IA, // ITLB invalidate all register - RAW_IPR_ITB_IAP, // ITLB invalidate all process register - - //Read only - RAW_IPR_INTID, // interrupt ID register - RAW_IPR_SL_RCV, // serial line receive register - RAW_IPR_MM_STAT, // data MMU fault status register - RAW_IPR_ITB_PTE_TEMP, // ITLB page table entry temp register - RAW_IPR_DTB_PTE_TEMP, // DTLB page table entry temporary register - - RAW_IPR_ISR, // interrupt summary register - RAW_IPR_ITB_TAG, // ITLB tag register - RAW_IPR_ITB_PTE, // ITLB page table entry register - RAW_IPR_ITB_ASN, // ITLB address space register - RAW_IPR_ITB_IS, // ITLB invalidate select register - RAW_IPR_SIRR, // software interrupt request register - RAW_IPR_ASTRR, // asynchronous system trap request register - RAW_IPR_ASTER, // asynchronous system trap enable register - RAW_IPR_EXC_ADDR, // exception address register - RAW_IPR_EXC_SUM, // exception summary register - RAW_IPR_EXC_MASK, // exception mask register - RAW_IPR_PAL_BASE, // PAL base address register - RAW_IPR_ICM, // instruction current mode - RAW_IPR_IPLR, // interrupt priority level register - RAW_IPR_IFAULT_VA_FORM, // formatted faulting virtual addr register - RAW_IPR_IVPTBR, // virtual page table base register - RAW_IPR_ICSR, // instruction control and status register - RAW_IPR_IC_PERR_STAT, // inst cache parity error status register - RAW_IPR_PMCTR, // performance counter register - - // PAL temporary registers... - // register meanings gleaned from osfpal.s source code - RAW_IPR_PALtemp0, // local scratch - RAW_IPR_PALtemp1, // local scratch - RAW_IPR_PALtemp2, // entUna - RAW_IPR_PALtemp3, // CPU specific impure area pointer - RAW_IPR_PALtemp4, // memory management temp - RAW_IPR_PALtemp5, // memory management temp - RAW_IPR_PALtemp6, // memory management temp - RAW_IPR_PALtemp7, // entIF - RAW_IPR_PALtemp8, // intmask - RAW_IPR_PALtemp9, // entSys - RAW_IPR_PALtemp10, // ?? - RAW_IPR_PALtemp11, // entInt - RAW_IPR_PALtemp12, // entArith - RAW_IPR_PALtemp13, // reserved for platform specific PAL - RAW_IPR_PALtemp14, // reserved for platform specific PAL - RAW_IPR_PALtemp15, // reserved for platform specific PAL - RAW_IPR_PALtemp16, // scratch / whami<7:0> / mces<4:0> - RAW_IPR_PALtemp17, // sysval - RAW_IPR_PALtemp18, // usp - RAW_IPR_PALtemp19, // ksp - RAW_IPR_PALtemp20, // PTBR - RAW_IPR_PALtemp21, // entMM - RAW_IPR_PALtemp22, // kgp - RAW_IPR_PALtemp23, // PCBB - - RAW_IPR_DTB_ASN, // DTLB address space number register - RAW_IPR_DTB_CM, // DTLB current mode register - RAW_IPR_DTB_TAG, // DTLB tag register - RAW_IPR_DTB_PTE, // DTLB page table entry register - - RAW_IPR_VA, // fault virtual address register - RAW_IPR_VA_FORM, // formatted virtual address register - RAW_IPR_MVPTBR, // MTU virtual page table base register - RAW_IPR_DTB_IS, // DTLB invalidate single register - RAW_IPR_CC, // cycle counter register - RAW_IPR_CC_CTL, // cycle counter control register - RAW_IPR_MCSR, // MTU control register - - RAW_IPR_DC_PERR_STAT, // Dcache parity error status register - RAW_IPR_DC_TEST_CTL, // Dcache test tag control register - RAW_IPR_DC_TEST_TAG, // Dcache test tag register - RAW_IPR_DC_TEST_TAG_TEMP, // Dcache test tag temporary register - RAW_IPR_DC_MODE, // Dcache mode register - RAW_IPR_MAF_MODE // miss address file mode register - }; - - int IprToMiscRegIndex[MaxInternalProcRegs]; - - void initializeIprTable() - { - static bool initialized = false; - if(initialized) - return; - - memset(IprToMiscRegIndex, -1, MaxInternalProcRegs * sizeof(int)); - - for(int x = 0; x < NumInternalProcRegs; x++) - IprToMiscRegIndex[MiscRegIndexToIpr[x]] = x; - } + static bool initialized = false; + if (initialized) + return; + + memset(IprToMiscRegIndex, -1, MaxInternalProcRegs * sizeof(int)); + + for (int x = 0; x < NumInternalProcRegs; x++) + IprToMiscRegIndex[MiscRegIndexToIpr[x]] = x; } +} // namespace AlphaISA + diff --git a/src/arch/alpha/ipr.hh b/src/arch/alpha/ipr.hh index 6296cdb9a..4e7bf1fa4 100644 --- a/src/arch/alpha/ipr.hh +++ b/src/arch/alpha/ipr.hh @@ -32,206 +32,208 @@ #ifndef __ARCH_ALPHA_IPR_HH__ #define __ARCH_ALPHA_IPR_HH__ -namespace AlphaISA +namespace AlphaISA { + +//////////////////////////////////////////////////////////////////////// +// +// Internal Processor Reigsters +// +enum md_ipr_names { + RAW_IPR_ISR = 0x100, // interrupt summary + RAW_IPR_ITB_TAG = 0x101, // ITLB tag + RAW_IPR_ITB_PTE = 0x102, // ITLB page table entry + RAW_IPR_ITB_ASN = 0x103, // ITLB address space + RAW_IPR_ITB_PTE_TEMP = 0x104, // ITLB page table entry temp + RAW_IPR_ITB_IA = 0x105, // ITLB invalidate all + RAW_IPR_ITB_IAP = 0x106, // ITLB invalidate all process + RAW_IPR_ITB_IS = 0x107, // ITLB invalidate select + RAW_IPR_SIRR = 0x108, // software interrupt request + RAW_IPR_ASTRR = 0x109, // asynchronous system trap request + RAW_IPR_ASTER = 0x10a, // asynchronous system trap enable + RAW_IPR_EXC_ADDR = 0x10b, // exception address + RAW_IPR_EXC_SUM = 0x10c, // exception summary + RAW_IPR_EXC_MASK = 0x10d, // exception mask + RAW_IPR_PAL_BASE = 0x10e, // PAL base address + RAW_IPR_ICM = 0x10f, // instruction current mode + RAW_IPR_IPLR = 0x110, // interrupt priority level + RAW_IPR_INTID = 0x111, // interrupt ID + RAW_IPR_IFAULT_VA_FORM = 0x112, // formatted faulting virtual addr + RAW_IPR_IVPTBR = 0x113, // virtual page table base + RAW_IPR_HWINT_CLR = 0x115, // H/W interrupt clear + RAW_IPR_SL_XMIT = 0x116, // serial line transmit + RAW_IPR_SL_RCV = 0x117, // serial line receive + RAW_IPR_ICSR = 0x118, // instruction control and status + RAW_IPR_IC_FLUSH = 0x119, // instruction cache flush control + RAW_IPR_IC_PERR_STAT = 0x11a, // inst cache parity error status + RAW_IPR_PMCTR = 0x11c, // performance counter + + // PAL temporary registers... + // register meanings gleaned from osfpal.s source code + RAW_IPR_PALtemp0 = 0x140, // local scratch + RAW_IPR_PALtemp1 = 0x141, // local scratch + RAW_IPR_PALtemp2 = 0x142, // entUna + RAW_IPR_PALtemp3 = 0x143, // CPU specific impure area pointer + RAW_IPR_PALtemp4 = 0x144, // memory management temp + RAW_IPR_PALtemp5 = 0x145, // memory management temp + RAW_IPR_PALtemp6 = 0x146, // memory management temp + RAW_IPR_PALtemp7 = 0x147, // entIF + RAW_IPR_PALtemp8 = 0x148, // intmask + RAW_IPR_PALtemp9 = 0x149, // entSys + RAW_IPR_PALtemp10 = 0x14a, // ?? + RAW_IPR_PALtemp11 = 0x14b, // entInt + RAW_IPR_PALtemp12 = 0x14c, // entArith + RAW_IPR_PALtemp13 = 0x14d, // reserved for platform specific PAL + RAW_IPR_PALtemp14 = 0x14e, // reserved for platform specific PAL + RAW_IPR_PALtemp15 = 0x14f, // reserved for platform specific PAL + RAW_IPR_PALtemp16 = 0x150, // scratch / whami<7:0> / mces<4:0> + RAW_IPR_PALtemp17 = 0x151, // sysval + RAW_IPR_PALtemp18 = 0x152, // usp + RAW_IPR_PALtemp19 = 0x153, // ksp + RAW_IPR_PALtemp20 = 0x154, // PTBR + RAW_IPR_PALtemp21 = 0x155, // entMM + RAW_IPR_PALtemp22 = 0x156, // kgp + RAW_IPR_PALtemp23 = 0x157, // PCBB + + RAW_IPR_DTB_ASN = 0x200, // DTLB address space number + RAW_IPR_DTB_CM = 0x201, // DTLB current mode + RAW_IPR_DTB_TAG = 0x202, // DTLB tag + RAW_IPR_DTB_PTE = 0x203, // DTLB page table entry + RAW_IPR_DTB_PTE_TEMP = 0x204, // DTLB page table entry temporary + + RAW_IPR_MM_STAT = 0x205, // data MMU fault status + RAW_IPR_VA = 0x206, // fault virtual address + RAW_IPR_VA_FORM = 0x207, // formatted virtual address + RAW_IPR_MVPTBR = 0x208, // MTU virtual page table base + RAW_IPR_DTB_IAP = 0x209, // DTLB invalidate all process + RAW_IPR_DTB_IA = 0x20a, // DTLB invalidate all + RAW_IPR_DTB_IS = 0x20b, // DTLB invalidate single + RAW_IPR_ALT_MODE = 0x20c, // alternate mode + RAW_IPR_CC = 0x20d, // cycle counter + RAW_IPR_CC_CTL = 0x20e, // cycle counter control + RAW_IPR_MCSR = 0x20f, // MTU control + + RAW_IPR_DC_FLUSH = 0x210, + RAW_IPR_DC_PERR_STAT = 0x212, // Dcache parity error status + RAW_IPR_DC_TEST_CTL = 0x213, // Dcache test tag control + RAW_IPR_DC_TEST_TAG = 0x214, // Dcache test tag + RAW_IPR_DC_TEST_TAG_TEMP = 0x215, // Dcache test tag temporary + RAW_IPR_DC_MODE = 0x216, // Dcache mode + RAW_IPR_MAF_MODE = 0x217, // miss address file mode + + MaxInternalProcRegs // number of IPRs +}; + +enum MiscRegIpr { - //////////////////////////////////////////////////////////////////////// - // - // Internal Processor Reigsters - // - enum md_ipr_names - { - RAW_IPR_ISR = 0x100, // interrupt summary register - RAW_IPR_ITB_TAG = 0x101, // ITLB tag register - RAW_IPR_ITB_PTE = 0x102, // ITLB page table entry register - RAW_IPR_ITB_ASN = 0x103, // ITLB address space register - RAW_IPR_ITB_PTE_TEMP = 0x104, // ITLB page table entry temp register - RAW_IPR_ITB_IA = 0x105, // ITLB invalidate all register - RAW_IPR_ITB_IAP = 0x106, // ITLB invalidate all process register - RAW_IPR_ITB_IS = 0x107, // ITLB invalidate select register - RAW_IPR_SIRR = 0x108, // software interrupt request register - RAW_IPR_ASTRR = 0x109, // asynchronous system trap request register - RAW_IPR_ASTER = 0x10a, // asynchronous system trap enable register - RAW_IPR_EXC_ADDR = 0x10b, // exception address register - RAW_IPR_EXC_SUM = 0x10c, // exception summary register - RAW_IPR_EXC_MASK = 0x10d, // exception mask register - RAW_IPR_PAL_BASE = 0x10e, // PAL base address register - RAW_IPR_ICM = 0x10f, // instruction current mode - RAW_IPR_IPLR = 0x110, // interrupt priority level register - RAW_IPR_INTID = 0x111, // interrupt ID register - RAW_IPR_IFAULT_VA_FORM = 0x112, // formatted faulting virtual addr register - RAW_IPR_IVPTBR = 0x113, // virtual page table base register - RAW_IPR_HWINT_CLR = 0x115, // H/W interrupt clear register - RAW_IPR_SL_XMIT = 0x116, // serial line transmit register - RAW_IPR_SL_RCV = 0x117, // serial line receive register - RAW_IPR_ICSR = 0x118, // instruction control and status register - RAW_IPR_IC_FLUSH = 0x119, // instruction cache flush control - RAW_IPR_IC_PERR_STAT = 0x11a, // inst cache parity error status register - RAW_IPR_PMCTR = 0x11c, // performance counter register - - // PAL temporary registers... - // register meanings gleaned from osfpal.s source code - RAW_IPR_PALtemp0 = 0x140, // local scratch - RAW_IPR_PALtemp1 = 0x141, // local scratch - RAW_IPR_PALtemp2 = 0x142, // entUna - RAW_IPR_PALtemp3 = 0x143, // CPU specific impure area pointer - RAW_IPR_PALtemp4 = 0x144, // memory management temp - RAW_IPR_PALtemp5 = 0x145, // memory management temp - RAW_IPR_PALtemp6 = 0x146, // memory management temp - RAW_IPR_PALtemp7 = 0x147, // entIF - RAW_IPR_PALtemp8 = 0x148, // intmask - RAW_IPR_PALtemp9 = 0x149, // entSys - RAW_IPR_PALtemp10 = 0x14a, // ?? - RAW_IPR_PALtemp11 = 0x14b, // entInt - RAW_IPR_PALtemp12 = 0x14c, // entArith - RAW_IPR_PALtemp13 = 0x14d, // reserved for platform specific PAL - RAW_IPR_PALtemp14 = 0x14e, // reserved for platform specific PAL - RAW_IPR_PALtemp15 = 0x14f, // reserved for platform specific PAL - RAW_IPR_PALtemp16 = 0x150, // scratch / whami<7:0> / mces<4:0> - RAW_IPR_PALtemp17 = 0x151, // sysval - RAW_IPR_PALtemp18 = 0x152, // usp - RAW_IPR_PALtemp19 = 0x153, // ksp - RAW_IPR_PALtemp20 = 0x154, // PTBR - RAW_IPR_PALtemp21 = 0x155, // entMM - RAW_IPR_PALtemp22 = 0x156, // kgp - RAW_IPR_PALtemp23 = 0x157, // PCBB - - RAW_IPR_DTB_ASN = 0x200, // DTLB address space number register - RAW_IPR_DTB_CM = 0x201, // DTLB current mode register - RAW_IPR_DTB_TAG = 0x202, // DTLB tag register - RAW_IPR_DTB_PTE = 0x203, // DTLB page table entry register - RAW_IPR_DTB_PTE_TEMP = 0x204, // DTLB page table entry temporary register - - RAW_IPR_MM_STAT = 0x205, // data MMU fault status register - RAW_IPR_VA = 0x206, // fault virtual address register - RAW_IPR_VA_FORM = 0x207, // formatted virtual address register - RAW_IPR_MVPTBR = 0x208, // MTU virtual page table base register - RAW_IPR_DTB_IAP = 0x209, // DTLB invalidate all process register - RAW_IPR_DTB_IA = 0x20a, // DTLB invalidate all register - RAW_IPR_DTB_IS = 0x20b, // DTLB invalidate single register - RAW_IPR_ALT_MODE = 0x20c, // alternate mode register - RAW_IPR_CC = 0x20d, // cycle counter register - RAW_IPR_CC_CTL = 0x20e, // cycle counter control register - RAW_IPR_MCSR = 0x20f, // MTU control register - - RAW_IPR_DC_FLUSH = 0x210, - RAW_IPR_DC_PERR_STAT = 0x212, // Dcache parity error status register - RAW_IPR_DC_TEST_CTL = 0x213, // Dcache test tag control register - RAW_IPR_DC_TEST_TAG = 0x214, // Dcache test tag register - RAW_IPR_DC_TEST_TAG_TEMP = 0x215, // Dcache test tag temporary register - RAW_IPR_DC_MODE = 0x216, // Dcache mode register - RAW_IPR_MAF_MODE = 0x217, // miss address file mode register - - MaxInternalProcRegs // number of IPR registers - }; - - enum MiscRegIpr - { - //Write only - MinWriteOnlyIpr, - IPR_HWINT_CLR = MinWriteOnlyIpr, - IPR_SL_XMIT, - IPR_DC_FLUSH, - IPR_IC_FLUSH, - IPR_ALT_MODE, - IPR_DTB_IA, - IPR_DTB_IAP, - IPR_ITB_IA, - MaxWriteOnlyIpr, - IPR_ITB_IAP = MaxWriteOnlyIpr, - - //Read only - MinReadOnlyIpr, - IPR_INTID = MinReadOnlyIpr, - IPR_SL_RCV, - IPR_MM_STAT, - IPR_ITB_PTE_TEMP, - MaxReadOnlyIpr, - IPR_DTB_PTE_TEMP = MaxReadOnlyIpr, - - IPR_ISR, - IPR_ITB_TAG, - IPR_ITB_PTE, - IPR_ITB_ASN, - IPR_ITB_IS, - IPR_SIRR, - IPR_ASTRR, - IPR_ASTER, - IPR_EXC_ADDR, - IPR_EXC_SUM, - IPR_EXC_MASK, - IPR_PAL_BASE, - IPR_ICM, - IPR_IPLR, - IPR_IFAULT_VA_FORM, - IPR_IVPTBR, - IPR_ICSR, - IPR_IC_PERR_STAT, - IPR_PMCTR, - - // PAL temporary registers... - // register meanings gleaned from osfpal.s source code - IPR_PALtemp0, - IPR_PALtemp1, - IPR_PALtemp2, - IPR_PALtemp3, - IPR_PALtemp4, - IPR_PALtemp5, - IPR_PALtemp6, - IPR_PALtemp7, - IPR_PALtemp8, - IPR_PALtemp9, - IPR_PALtemp10, - IPR_PALtemp11, - IPR_PALtemp12, - IPR_PALtemp13, - IPR_PALtemp14, - IPR_PALtemp15, - IPR_PALtemp16, - IPR_PALtemp17, - IPR_PALtemp18, - IPR_PALtemp19, - IPR_PALtemp20, - IPR_PALtemp21, - IPR_PALtemp22, - IPR_PALtemp23, - - IPR_DTB_ASN, - IPR_DTB_CM, - IPR_DTB_TAG, - IPR_DTB_PTE, - - IPR_VA, - IPR_VA_FORM, - IPR_MVPTBR, - IPR_DTB_IS, - IPR_CC, - IPR_CC_CTL, - IPR_MCSR, - - IPR_DC_PERR_STAT, - IPR_DC_TEST_CTL, - IPR_DC_TEST_TAG, - IPR_DC_TEST_TAG_TEMP, - IPR_DC_MODE, - IPR_MAF_MODE, - - NumInternalProcRegs // number of IPR registers - }; - - inline bool IprIsWritable(int index) - { - return index < MinReadOnlyIpr || index > MaxReadOnlyIpr; - } - - inline bool IprIsReadable(int index) - { - return index < MinWriteOnlyIpr || index > MaxWriteOnlyIpr; - } - - extern md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs]; - extern int IprToMiscRegIndex[MaxInternalProcRegs]; - - void initializeIprTable(); + //Write only + MinWriteOnlyIpr, + IPR_HWINT_CLR = MinWriteOnlyIpr, + IPR_SL_XMIT, + IPR_DC_FLUSH, + IPR_IC_FLUSH, + IPR_ALT_MODE, + IPR_DTB_IA, + IPR_DTB_IAP, + IPR_ITB_IA, + MaxWriteOnlyIpr, + IPR_ITB_IAP = MaxWriteOnlyIpr, + + //Read only + MinReadOnlyIpr, + IPR_INTID = MinReadOnlyIpr, + IPR_SL_RCV, + IPR_MM_STAT, + IPR_ITB_PTE_TEMP, + MaxReadOnlyIpr, + IPR_DTB_PTE_TEMP = MaxReadOnlyIpr, + + IPR_ISR, + IPR_ITB_TAG, + IPR_ITB_PTE, + IPR_ITB_ASN, + IPR_ITB_IS, + IPR_SIRR, + IPR_ASTRR, + IPR_ASTER, + IPR_EXC_ADDR, + IPR_EXC_SUM, + IPR_EXC_MASK, + IPR_PAL_BASE, + IPR_ICM, + IPR_IPLR, + IPR_IFAULT_VA_FORM, + IPR_IVPTBR, + IPR_ICSR, + IPR_IC_PERR_STAT, + IPR_PMCTR, + + // PAL temporary registers... + // register meanings gleaned from osfpal.s source code + IPR_PALtemp0, + IPR_PALtemp1, + IPR_PALtemp2, + IPR_PALtemp3, + IPR_PALtemp4, + IPR_PALtemp5, + IPR_PALtemp6, + IPR_PALtemp7, + IPR_PALtemp8, + IPR_PALtemp9, + IPR_PALtemp10, + IPR_PALtemp11, + IPR_PALtemp12, + IPR_PALtemp13, + IPR_PALtemp14, + IPR_PALtemp15, + IPR_PALtemp16, + IPR_PALtemp17, + IPR_PALtemp18, + IPR_PALtemp19, + IPR_PALtemp20, + IPR_PALtemp21, + IPR_PALtemp22, + IPR_PALtemp23, + + IPR_DTB_ASN, + IPR_DTB_CM, + IPR_DTB_TAG, + IPR_DTB_PTE, + + IPR_VA, + IPR_VA_FORM, + IPR_MVPTBR, + IPR_DTB_IS, + IPR_CC, + IPR_CC_CTL, + IPR_MCSR, + + IPR_DC_PERR_STAT, + IPR_DC_TEST_CTL, + IPR_DC_TEST_TAG, + IPR_DC_TEST_TAG_TEMP, + IPR_DC_MODE, + IPR_MAF_MODE, + + NumInternalProcRegs // number of IPR registers +}; + +inline bool +IprIsWritable(int index) +{ + return index < MinReadOnlyIpr || index > MaxReadOnlyIpr; +} + +inline bool +IprIsReadable(int index) +{ + return index < MinWriteOnlyIpr || index > MaxWriteOnlyIpr; } -#endif +extern md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs]; +extern int IprToMiscRegIndex[MaxInternalProcRegs]; + +void initializeIprTable(); + +} // namespace AlphaISA + +#endif // __ARCH_ALPHA_IPR_HH__ diff --git a/src/arch/alpha/isa_traits.hh b/src/arch/alpha/isa_traits.hh index 4837d4a34..e5e4542a7 100644 --- a/src/arch/alpha/isa_traits.hh +++ b/src/arch/alpha/isa_traits.hh @@ -42,142 +42,137 @@ namespace LittleEndianGuest {} class StaticInstPtr; -namespace AlphaISA +namespace AlphaISA { + +using namespace LittleEndianGuest; +using AlphaISAInst::MaxInstSrcRegs; +using AlphaISAInst::MaxInstDestRegs; + +// These enumerate all the registers for dependence tracking. +enum DependenceTags { + // 0..31 are the integer regs 0..31 + // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag) + FP_Base_DepTag = 40, + Ctrl_Base_DepTag = 72 +}; + +StaticInstPtr decodeInst(ExtMachInst); + +// Alpha Does NOT have a delay slot +#define ISA_HAS_DELAY_SLOT 0 + +const Addr PageShift = 13; +const Addr PageBytes = ULL(1) << PageShift; +const Addr PageMask = ~(PageBytes - 1); +const Addr PageOffset = PageBytes - 1; + +//////////////////////////////////////////////////////////////////////// +// +// Translation stuff +// + +const Addr PteShift = 3; +const Addr NPtePageShift = PageShift - PteShift; +const Addr NPtePage = ULL(1) << NPtePageShift; +const Addr PteMask = NPtePage - 1; + +// User Virtual +const Addr USegBase = ULL(0x0); +const Addr USegEnd = ULL(0x000003ffffffffff); + +// Kernel Direct Mapped +const Addr K0SegBase = ULL(0xfffffc0000000000); +const Addr K0SegEnd = ULL(0xfffffdffffffffff); + +// Kernel Virtual +const Addr K1SegBase = ULL(0xfffffe0000000000); +const Addr K1SegEnd = ULL(0xffffffffffffffff); + +// For loading... XXX This maybe could be USegEnd?? --ali +const Addr LoadAddrMask = ULL(0xffffffffff); + +//////////////////////////////////////////////////////////////////////// +// +// Interrupt levels +// +enum InterruptLevels { - using namespace LittleEndianGuest; - using AlphaISAInst::MaxInstSrcRegs; - using AlphaISAInst::MaxInstDestRegs; - - // These enumerate all the registers for dependence tracking. - enum DependenceTags { - // 0..31 are the integer regs 0..31 - // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag) - FP_Base_DepTag = 40, - Ctrl_Base_DepTag = 72 - }; - - StaticInstPtr decodeInst(ExtMachInst); - - // Alpha Does NOT have a delay slot - #define ISA_HAS_DELAY_SLOT 0 - - const Addr PageShift = 13; - const Addr PageBytes = ULL(1) << PageShift; - const Addr PageMask = ~(PageBytes - 1); - const Addr PageOffset = PageBytes - 1; - - - //////////////////////////////////////////////////////////////////////// - // - // Translation stuff - // - - const Addr PteShift = 3; - const Addr NPtePageShift = PageShift - PteShift; - const Addr NPtePage = ULL(1) << NPtePageShift; - const Addr PteMask = NPtePage - 1; - - // User Virtual - const Addr USegBase = ULL(0x0); - const Addr USegEnd = ULL(0x000003ffffffffff); - - // Kernel Direct Mapped - const Addr K0SegBase = ULL(0xfffffc0000000000); - const Addr K0SegEnd = ULL(0xfffffdffffffffff); - - // Kernel Virtual - const Addr K1SegBase = ULL(0xfffffe0000000000); - const Addr K1SegEnd = ULL(0xffffffffffffffff); - - // For loading... XXX This maybe could be USegEnd?? --ali - const Addr LoadAddrMask = ULL(0xffffffffff); - -#if FULL_SYSTEM - - //////////////////////////////////////////////////////////////////////// - // - // Interrupt levels - // - enum InterruptLevels - { - INTLEVEL_SOFTWARE_MIN = 4, - INTLEVEL_SOFTWARE_MAX = 19, - - INTLEVEL_EXTERNAL_MIN = 20, - INTLEVEL_EXTERNAL_MAX = 34, - - INTLEVEL_IRQ0 = 20, - INTLEVEL_IRQ1 = 21, - INTINDEX_ETHERNET = 0, - INTINDEX_SCSI = 1, - INTLEVEL_IRQ2 = 22, - INTLEVEL_IRQ3 = 23, - - INTLEVEL_SERIAL = 33, - - NumInterruptLevels = INTLEVEL_EXTERNAL_MAX - }; - -#endif - - // EV5 modes - enum mode_type - { - mode_kernel = 0, // kernel - mode_executive = 1, // executive (unused by unix) - mode_supervisor = 2, // supervisor (unused by unix) - mode_user = 3, // user mode - mode_number // number of modes - }; - - // Constants Related to the number of registers - - const int NumIntArchRegs = 32; - const int NumPALShadowRegs = 8; - const int NumFloatArchRegs = 32; - // @todo: Figure out what this number really should be. - const int NumMiscArchRegs = 77; - - const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs; - const int NumFloatRegs = NumFloatArchRegs; - const int NumMiscRegs = NumMiscArchRegs; - - const int TotalNumRegs = NumIntRegs + NumFloatRegs + - NumMiscRegs + NumInternalProcRegs; - - const int TotalDataRegs = NumIntRegs + NumFloatRegs; - - // semantically meaningful register indices - const int ZeroReg = 31; // architecturally meaningful - // the rest of these depend on the ABI - const int StackPointerReg = 30; - const int GlobalPointerReg = 29; - const int ProcedureValueReg = 27; - const int ReturnAddressReg = 26; - const int ReturnValueReg = 0; - const int FramePointerReg = 15; + INTLEVEL_SOFTWARE_MIN = 4, + INTLEVEL_SOFTWARE_MAX = 19, - const int ArgumentReg[] = {16, 17, 18, 19, 20, 21}; - const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int); + INTLEVEL_EXTERNAL_MIN = 20, + INTLEVEL_EXTERNAL_MAX = 34, - const int SyscallNumReg = ReturnValueReg; - const int SyscallPseudoReturnReg = ArgumentReg[4]; - const int SyscallSuccessReg = 19; + INTLEVEL_IRQ0 = 20, + INTLEVEL_IRQ1 = 21, + INTINDEX_ETHERNET = 0, + INTINDEX_SCSI = 1, + INTLEVEL_IRQ2 = 22, + INTLEVEL_IRQ3 = 23, - const int LogVMPageSize = 13; // 8K bytes - const int VMPageSize = (1 << LogVMPageSize); - - const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned - - const int MachineBytes = 8; - const int WordBytes = 4; - const int HalfwordBytes = 2; - const int ByteBytes = 1; - - // return a no-op instruction... used for instruction fetch faults - // Alpha UNOP (ldq_u r31,0(r0)) - const ExtMachInst NoopMachInst = 0x2ffe0000; + INTLEVEL_SERIAL = 33, + NumInterruptLevels = INTLEVEL_EXTERNAL_MAX +}; + +// EV5 modes +enum mode_type +{ + mode_kernel = 0, // kernel + mode_executive = 1, // executive (unused by unix) + mode_supervisor = 2, // supervisor (unused by unix) + mode_user = 3, // user mode + mode_number // number of modes }; +// Constants Related to the number of registers + +const int NumIntArchRegs = 32; +const int NumPALShadowRegs = 8; +const int NumFloatArchRegs = 32; +// @todo: Figure out what this number really should be. +const int NumMiscArchRegs = 77; + +const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs; +const int NumFloatRegs = NumFloatArchRegs; +const int NumMiscRegs = NumMiscArchRegs; + +const int TotalNumRegs = + NumIntRegs + NumFloatRegs + NumMiscRegs + NumInternalProcRegs; + +const int TotalDataRegs = NumIntRegs + NumFloatRegs; + +// semantically meaningful register indices +const int ZeroReg = 31; // architecturally meaningful +// the rest of these depend on the ABI +const int StackPointerReg = 30; +const int GlobalPointerReg = 29; +const int ProcedureValueReg = 27; +const int ReturnAddressReg = 26; +const int ReturnValueReg = 0; +const int FramePointerReg = 15; + +const int ArgumentReg[] = {16, 17, 18, 19, 20, 21}; +const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int); + +const int SyscallNumReg = ReturnValueReg; +const int SyscallPseudoReturnReg = ArgumentReg[4]; +const int SyscallSuccessReg = 19; + +const int LogVMPageSize = 13; // 8K bytes +const int VMPageSize = (1 << LogVMPageSize); + +const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned + +const int MachineBytes = 8; +const int WordBytes = 4; +const int HalfwordBytes = 2; +const int ByteBytes = 1; + +// return a no-op instruction... used for instruction fetch faults +// Alpha UNOP (ldq_u r31,0(r0)) +const ExtMachInst NoopMachInst = 0x2ffe0000; + +} // namespace AlphaISA + #endif // __ARCH_ALPHA_ISA_TRAITS_HH__ diff --git a/src/arch/alpha/linux/linux.cc b/src/arch/alpha/linux/linux.cc index 3e80f62a7..ad8388096 100644 --- a/src/arch/alpha/linux/linux.cc +++ b/src/arch/alpha/linux/linux.cc @@ -28,10 +28,10 @@ * Authors: Korey Sewell */ -#include "arch/alpha/linux/linux.hh" - #include +#include "arch/alpha/linux/linux.hh" + // open(2) flags translation table OpenFlagTransTable AlphaLinux::openFlagTable[] = { #ifdef _MSC_VER @@ -68,7 +68,4 @@ OpenFlagTransTable AlphaLinux::openFlagTable[] = { }; const int AlphaLinux::NUM_OPEN_FLAGS = - (sizeof(AlphaLinux::openFlagTable)/sizeof(AlphaLinux::openFlagTable[0])); - - - + (sizeof(AlphaLinux::openFlagTable)/sizeof(AlphaLinux::openFlagTable[0])); diff --git a/src/arch/alpha/linux/linux.hh b/src/arch/alpha/linux/linux.hh index 803970aa9..c622c5ef1 100644 --- a/src/arch/alpha/linux/linux.hh +++ b/src/arch/alpha/linux/linux.hh @@ -28,8 +28,8 @@ * Authors: Korey Sewell */ -#ifndef __ALPHA_ALPHA_LINUX_HH -#define __ALPHA_ALPHA_LINUX_HH +#ifndef __ALPHA_ALPHA_LINUX_LINUX_HH__ +#define __ALPHA_ALPHA_LINUX_LINUX_HH__ #include "kern/linux/linux.hh" @@ -72,13 +72,13 @@ class AlphaLinux : public Linux //@{ /// For getsysinfo(). - static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string - static const unsigned GSI_CPU_INFO = 59; //!< CPU information - static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type - static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine - static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system - static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB - static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz + static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string + static const unsigned GSI_CPU_INFO = 59; //!< CPU information + static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type + static const unsigned GSI_MAX_CPU = 30; //!< max # CPUs on machine + static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system + static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB + static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz static const unsigned GSI_IEEE_FP_CONTROL = 45; //@} @@ -127,4 +127,4 @@ class AlphaLinux : public Linux }; }; -#endif +#endif // __ALPHA_ALPHA_LINUX_LINUX_HH__ diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc index 0a9d2f1a3..9527759ed 100644 --- a/src/arch/alpha/linux/process.cc +++ b/src/arch/alpha/linux/process.cc @@ -43,8 +43,6 @@ using namespace std; using namespace AlphaISA; - - /// Target uname() handler. static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, diff --git a/src/arch/alpha/linux/process.hh b/src/arch/alpha/linux/process.hh index 8d7c24e37..9ab7b0501 100644 --- a/src/arch/alpha/linux/process.hh +++ b/src/arch/alpha/linux/process.hh @@ -51,4 +51,5 @@ class AlphaLinuxProcess : public AlphaLiveProcess }; } // namespace AlphaISA + #endif // __ALPHA_LINUX_PROCESS_HH__ diff --git a/src/arch/alpha/linux/system.cc b/src/arch/alpha/linux/system.cc index a52bcae36..1d9332a58 100644 --- a/src/arch/alpha/linux/system.cc +++ b/src/arch/alpha/linux/system.cc @@ -157,7 +157,6 @@ LinuxAlphaSystem::~LinuxAlphaSystem() delete printThreadEvent; } - void LinuxAlphaSystem::setDelayLoop(ThreadContext *tc) { @@ -172,7 +171,6 @@ LinuxAlphaSystem::setDelayLoop(ThreadContext *tc) } } - void LinuxAlphaSystem::SkipDelayLoopEvent::process(ThreadContext *tc) { diff --git a/src/arch/alpha/linux/system.hh b/src/arch/alpha/linux/system.hh index 00cde826a..fa03736c3 100644 --- a/src/arch/alpha/linux/system.hh +++ b/src/arch/alpha/linux/system.hh @@ -54,23 +54,20 @@ using namespace Linux; class LinuxAlphaSystem : public AlphaSystem { private: - class SkipDelayLoopEvent : public SkipFuncEvent + struct SkipDelayLoopEvent : public SkipFuncEvent { - public: SkipDelayLoopEvent(PCEventQueue *q, const std::string &desc, Addr addr) : SkipFuncEvent(q, desc, addr) {} virtual void process(ThreadContext *tc); }; - class PrintThreadInfo : public PCEvent + struct PrintThreadInfo : public PCEvent { - public: PrintThreadInfo(PCEventQueue *q, const std::string &desc, Addr addr) : PCEvent(q, desc, addr) {} virtual void process(ThreadContext *tc); }; - /** * Addresses defining where the kernel bootloader places various * elements. Details found in include/asm-alpha/system.h diff --git a/src/arch/alpha/linux/threadinfo.hh b/src/arch/alpha/linux/threadinfo.hh index 3ec1aa098..db723bed3 100644 --- a/src/arch/alpha/linux/threadinfo.hh +++ b/src/arch/alpha/linux/threadinfo.hh @@ -147,6 +147,6 @@ class ThreadInfo } }; -/* namespace Linux */ } +} // namespace Linux #endif // __ARCH_ALPHA_LINUX_LINUX_THREADINFO_HH__ diff --git a/src/arch/alpha/locked_mem.hh b/src/arch/alpha/locked_mem.hh index df66b92bc..f629d982a 100644 --- a/src/arch/alpha/locked_mem.hh +++ b/src/arch/alpha/locked_mem.hh @@ -49,9 +49,8 @@ #include "base/misc.hh" #include "mem/request.hh" +namespace AlphaISA { -namespace AlphaISA -{ template inline void handleLockedRead(XC *xc, Request *req) @@ -99,7 +98,6 @@ handleLockedWrite(XC *xc, Request *req) return true; } - } // namespace AlphaISA -#endif +#endif // __ARCH_ALPHA_LOCKED_MEM_HH__ diff --git a/src/arch/alpha/miscregfile.cc b/src/arch/alpha/miscregfile.cc index cb5875349..f119ca6bb 100644 --- a/src/arch/alpha/miscregfile.cc +++ b/src/arch/alpha/miscregfile.cc @@ -33,118 +33,116 @@ #include "arch/alpha/miscregfile.hh" #include "base/misc.hh" -namespace AlphaISA -{ +namespace AlphaISA { - void - MiscRegFile::serialize(std::ostream &os) - { - SERIALIZE_SCALAR(fpcr); - SERIALIZE_SCALAR(uniq); - SERIALIZE_SCALAR(lock_flag); - SERIALIZE_SCALAR(lock_addr); - SERIALIZE_ARRAY(ipr, NumInternalProcRegs); - } +void +MiscRegFile::serialize(std::ostream &os) +{ + SERIALIZE_SCALAR(fpcr); + SERIALIZE_SCALAR(uniq); + SERIALIZE_SCALAR(lock_flag); + SERIALIZE_SCALAR(lock_addr); + SERIALIZE_ARRAY(ipr, NumInternalProcRegs); +} - void - MiscRegFile::unserialize(Checkpoint *cp, const std::string §ion) - { - UNSERIALIZE_SCALAR(fpcr); - UNSERIALIZE_SCALAR(uniq); - UNSERIALIZE_SCALAR(lock_flag); - UNSERIALIZE_SCALAR(lock_addr); - UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs); - } +void +MiscRegFile::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_SCALAR(fpcr); + UNSERIALIZE_SCALAR(uniq); + UNSERIALIZE_SCALAR(lock_flag); + UNSERIALIZE_SCALAR(lock_addr); + UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs); +} - MiscReg - MiscRegFile::readRegNoEffect(int misc_reg) - { - switch(misc_reg) { - case MISCREG_FPCR: - return fpcr; - case MISCREG_UNIQ: - return uniq; - case MISCREG_LOCKFLAG: - return lock_flag; - case MISCREG_LOCKADDR: - return lock_addr; - case MISCREG_INTR: - return intr_flag; - default: - assert(misc_reg < NumInternalProcRegs); - return ipr[misc_reg]; - } +MiscReg +MiscRegFile::readRegNoEffect(int misc_reg) +{ + switch (misc_reg) { + case MISCREG_FPCR: + return fpcr; + case MISCREG_UNIQ: + return uniq; + case MISCREG_LOCKFLAG: + return lock_flag; + case MISCREG_LOCKADDR: + return lock_addr; + case MISCREG_INTR: + return intr_flag; + default: + assert(misc_reg < NumInternalProcRegs); + return ipr[misc_reg]; } +} - MiscReg - MiscRegFile::readReg(int misc_reg, ThreadContext *tc) - { - switch(misc_reg) { - case MISCREG_FPCR: - return fpcr; - case MISCREG_UNIQ: - return uniq; - case MISCREG_LOCKFLAG: - return lock_flag; - case MISCREG_LOCKADDR: - return lock_addr; - case MISCREG_INTR: - return intr_flag; - default: - return readIpr(misc_reg, tc); - } +MiscReg +MiscRegFile::readReg(int misc_reg, ThreadContext *tc) +{ + switch (misc_reg) { + case MISCREG_FPCR: + return fpcr; + case MISCREG_UNIQ: + return uniq; + case MISCREG_LOCKFLAG: + return lock_flag; + case MISCREG_LOCKADDR: + return lock_addr; + case MISCREG_INTR: + return intr_flag; + default: + return readIpr(misc_reg, tc); } +} - void - MiscRegFile::setRegNoEffect(int misc_reg, const MiscReg &val) - { - switch(misc_reg) { - case MISCREG_FPCR: - fpcr = val; - return; - case MISCREG_UNIQ: - uniq = val; - return; - case MISCREG_LOCKFLAG: - lock_flag = val; - return; - case MISCREG_LOCKADDR: - lock_addr = val; - return; - case MISCREG_INTR: - intr_flag = val; - return; - default: - assert(misc_reg < NumInternalProcRegs); - ipr[misc_reg] = val; - return; - } +void +MiscRegFile::setRegNoEffect(int misc_reg, const MiscReg &val) +{ + switch (misc_reg) { + case MISCREG_FPCR: + fpcr = val; + return; + case MISCREG_UNIQ: + uniq = val; + return; + case MISCREG_LOCKFLAG: + lock_flag = val; + return; + case MISCREG_LOCKADDR: + lock_addr = val; + return; + case MISCREG_INTR: + intr_flag = val; + return; + default: + assert(misc_reg < NumInternalProcRegs); + ipr[misc_reg] = val; + return; } +} - void - MiscRegFile::setReg(int misc_reg, const MiscReg &val, - ThreadContext *tc) - { - switch(misc_reg) { - case MISCREG_FPCR: - fpcr = val; - return; - case MISCREG_UNIQ: - uniq = val; - return; - case MISCREG_LOCKFLAG: - lock_flag = val; - return; - case MISCREG_LOCKADDR: - lock_addr = val; - return; - case MISCREG_INTR: - intr_flag = val; - return; - default: - setIpr(misc_reg, val, tc); - return; - } +void +MiscRegFile::setReg(int misc_reg, const MiscReg &val, ThreadContext *tc) +{ + switch (misc_reg) { + case MISCREG_FPCR: + fpcr = val; + return; + case MISCREG_UNIQ: + uniq = val; + return; + case MISCREG_LOCKFLAG: + lock_flag = val; + return; + case MISCREG_LOCKADDR: + lock_addr = val; + return; + case MISCREG_INTR: + intr_flag = val; + return; + default: + setIpr(misc_reg, val, tc); + return; } - } + +} // namespace AlphaISA diff --git a/src/arch/alpha/miscregfile.hh b/src/arch/alpha/miscregfile.hh index f07b998e6..752099d01 100644 --- a/src/arch/alpha/miscregfile.hh +++ b/src/arch/alpha/miscregfile.hh @@ -32,85 +32,85 @@ #ifndef __ARCH_ALPHA_MISCREGFILE_HH__ #define __ARCH_ALPHA_MISCREGFILE_HH__ +#include + #include "arch/alpha/ipr.hh" #include "arch/alpha/types.hh" #include "sim/host.hh" #include "sim/serialize.hh" -#include - class Checkpoint; class ThreadContext; -namespace AlphaISA -{ - enum MiscRegIndex - { - MISCREG_FPCR = NumInternalProcRegs, - MISCREG_UNIQ, - MISCREG_LOCKFLAG, - MISCREG_LOCKADDR, - MISCREG_INTR - }; - - static inline std::string getMiscRegName(RegIndex) - { - return ""; - } - - class MiscRegFile { - protected: - uint64_t fpcr; // floating point condition codes - uint64_t uniq; // process-unique register - bool lock_flag; // lock flag for LL/SC - Addr lock_addr; // lock address for LL/SC - int intr_flag; +namespace AlphaISA { - public: - MiscRegFile() - { - initializeIprTable(); - } - - MiscReg readRegNoEffect(int misc_reg); +enum MiscRegIndex +{ + MISCREG_FPCR = NumInternalProcRegs, + MISCREG_UNIQ, + MISCREG_LOCKFLAG, + MISCREG_LOCKADDR, + MISCREG_INTR +}; + +static inline std::string +getMiscRegName(RegIndex) +{ + return ""; +} - MiscReg readReg(int misc_reg, ThreadContext *tc); +class MiscRegFile +{ + public: + friend class RegFile; + typedef uint64_t InternalProcReg; - //These functions should be removed once the simplescalar cpu model - //has been replaced. - int getInstAsid(); - int getDataAsid(); + protected: + uint64_t fpcr; // floating point condition codes + uint64_t uniq; // process-unique register + bool lock_flag; // lock flag for LL/SC + Addr lock_addr; // lock address for LL/SC + int intr_flag; - void setRegNoEffect(int misc_reg, const MiscReg &val); + InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs - void setReg(int misc_reg, const MiscReg &val, - ThreadContext *tc); + protected: + InternalProcReg readIpr(int idx, ThreadContext *tc); + void setIpr(int idx, InternalProcReg val, ThreadContext *tc); - void clear() - { - fpcr = uniq = 0; - lock_flag = 0; - lock_addr = 0; - intr_flag = 0; - } + public: + MiscRegFile() + { + initializeIprTable(); + } - void serialize(std::ostream &os); + // These functions should be removed once the simplescalar cpu + // model has been replaced. + int getInstAsid(); + int getDataAsid(); - void unserialize(Checkpoint *cp, const std::string §ion); - protected: - typedef uint64_t InternalProcReg; + MiscReg readRegNoEffect(int misc_reg); + MiscReg readReg(int misc_reg, ThreadContext *tc); - InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs + void setRegNoEffect(int misc_reg, const MiscReg &val); + void setReg(int misc_reg, const MiscReg &val, ThreadContext *tc); - private: - InternalProcReg readIpr(int idx, ThreadContext *tc); + void + clear() + { + fpcr = 0; + uniq = 0; + lock_flag = 0; + lock_addr = 0; + intr_flag = 0; + } - void setIpr(int idx, InternalProcReg val, ThreadContext *tc); - friend class RegFile; - }; + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); +}; - void copyIprs(ThreadContext *src, ThreadContext *dest); +void copyIprs(ThreadContext *src, ThreadContext *dest); -} +} // namespace AlphaISA -#endif +#endif // __ARCH_ALPHA_MISCREGFILE_HH__ diff --git a/src/arch/alpha/mmaped_ipr.hh b/src/arch/alpha/mmaped_ipr.hh index 2b4ba8745..af2469ca7 100644 --- a/src/arch/alpha/mmaped_ipr.hh +++ b/src/arch/alpha/mmaped_ipr.hh @@ -39,9 +39,8 @@ #include "mem/packet.hh" +namespace AlphaISA { -namespace AlphaISA -{ inline Tick handleIprRead(ThreadContext *xc, Packet *pkt) { @@ -58,4 +57,4 @@ handleIprWrite(ThreadContext *xc, Packet *pkt) } // namespace AlphaISA -#endif +#endif // __ARCH_ALPHA_MMAPED_IPR_HH__ diff --git a/src/arch/alpha/osfpal.cc b/src/arch/alpha/osfpal.cc index 0edbadb06..58a3d31eb 100644 --- a/src/arch/alpha/osfpal.cc +++ b/src/arch/alpha/osfpal.cc @@ -30,8 +30,10 @@ #include "arch/alpha/osfpal.hh" -namespace { - const char *strings[PAL::NumCodes] = { +const char * +PAL::name(int index) +{ + static const char *strings[PAL::NumCodes] = { // Priviledged PAL instructions "halt", // 0x00 "cflush", // 0x01 @@ -294,11 +296,7 @@ namespace { 0 // 0xff #endif }; -} -const char * -PAL::name(int index) -{ if (index > NumCodes || index < 0) return 0; diff --git a/src/arch/alpha/osfpal.hh b/src/arch/alpha/osfpal.hh index cf3940b85..2618e9dbd 100644 --- a/src/arch/alpha/osfpal.hh +++ b/src/arch/alpha/osfpal.hh @@ -28,8 +28,8 @@ * Authors: Nathan Binkert */ -#ifndef __OSFPAL_HH__ -#define __OSFPAL_HH__ +#ifndef __ARCH_ALPHA_OSFPAL_HH__ +#define __ARCH_ALPHA_OSFPAL_HH__ struct PAL { @@ -79,4 +79,4 @@ struct PAL static const char *name(int index); }; -#endif // __OSFPAL_HH__ +#endif // __ARCH_ALPHA_OSFPAL_HH__ diff --git a/src/arch/alpha/pagetable.cc b/src/arch/alpha/pagetable.cc index 3f9537834..6640e72e2 100644 --- a/src/arch/alpha/pagetable.cc +++ b/src/arch/alpha/pagetable.cc @@ -31,33 +31,34 @@ #include "arch/alpha/pagetable.hh" #include "sim/serialize.hh" -namespace AlphaISA +namespace AlphaISA { + +void +TlbEntry::serialize(std::ostream &os) { - void - TlbEntry::serialize(std::ostream &os) - { - SERIALIZE_SCALAR(tag); - SERIALIZE_SCALAR(ppn); - SERIALIZE_SCALAR(xre); - SERIALIZE_SCALAR(xwe); - SERIALIZE_SCALAR(asn); - SERIALIZE_SCALAR(asma); - SERIALIZE_SCALAR(fonr); - SERIALIZE_SCALAR(fonw); - SERIALIZE_SCALAR(valid); - } + SERIALIZE_SCALAR(tag); + SERIALIZE_SCALAR(ppn); + SERIALIZE_SCALAR(xre); + SERIALIZE_SCALAR(xwe); + SERIALIZE_SCALAR(asn); + SERIALIZE_SCALAR(asma); + SERIALIZE_SCALAR(fonr); + SERIALIZE_SCALAR(fonw); + SERIALIZE_SCALAR(valid); +} - void - TlbEntry::unserialize(Checkpoint *cp, const std::string §ion) - { - UNSERIALIZE_SCALAR(tag); - UNSERIALIZE_SCALAR(ppn); - UNSERIALIZE_SCALAR(xre); - UNSERIALIZE_SCALAR(xwe); - UNSERIALIZE_SCALAR(asn); - UNSERIALIZE_SCALAR(asma); - UNSERIALIZE_SCALAR(fonr); - UNSERIALIZE_SCALAR(fonw); - UNSERIALIZE_SCALAR(valid); - } +void +TlbEntry::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_SCALAR(tag); + UNSERIALIZE_SCALAR(ppn); + UNSERIALIZE_SCALAR(xre); + UNSERIALIZE_SCALAR(xwe); + UNSERIALIZE_SCALAR(asn); + UNSERIALIZE_SCALAR(asma); + UNSERIALIZE_SCALAR(fonr); + UNSERIALIZE_SCALAR(fonw); + UNSERIALIZE_SCALAR(valid); } + +} //namespace AlphaISA diff --git a/src/arch/alpha/pagetable.hh b/src/arch/alpha/pagetable.hh index b0689dce0..4f7beb19b 100644 --- a/src/arch/alpha/pagetable.hh +++ b/src/arch/alpha/pagetable.hh @@ -38,97 +38,102 @@ namespace AlphaISA { - struct VAddr - { - static const int ImplBits = 43; - static const Addr ImplMask = (ULL(1) << ImplBits) - 1; - static const Addr UnImplMask = ~ImplMask; - - VAddr(Addr a) : addr(a) {} - Addr addr; - operator Addr() const { return addr; } - const VAddr &operator=(Addr a) { addr = a; return *this; } - - Addr vpn() const { return (addr & ImplMask) >> PageShift; } - Addr page() const { return addr & PageMask; } - Addr offset() const { return addr & PageOffset; } - - Addr level3() const - { return PteAddr(addr >> PageShift); } - Addr level2() const - { return PteAddr(addr >> NPtePageShift + PageShift); } - Addr level1() const - { return PteAddr(addr >> 2 * NPtePageShift + PageShift); } - }; - - struct PageTableEntry +struct VAddr +{ + static const int ImplBits = 43; + static const Addr ImplMask = (ULL(1) << ImplBits) - 1; + static const Addr UnImplMask = ~ImplMask; + + Addr addr; + + VAddr(Addr a) : addr(a) {} + operator Addr() const { return addr; } + const VAddr &operator=(Addr a) { addr = a; return *this; } + + Addr vpn() const { return (addr & ImplMask) >> PageShift; } + Addr page() const { return addr & PageMask; } + Addr offset() const { return addr & PageOffset; } + + Addr level3() const + { return PteAddr(addr >> PageShift); } + Addr level2() const + { return PteAddr(addr >> NPtePageShift + PageShift); } + Addr level1() const + { return PteAddr(addr >> 2 * NPtePageShift + PageShift); } +}; + +struct PageTableEntry +{ + PageTableEntry(uint64_t e) : entry(e) {} + uint64_t entry; + operator uint64_t() const { return entry; } + const PageTableEntry &operator=(uint64_t e) { entry = e; return *this; } + const PageTableEntry &operator=(const PageTableEntry &e) + { entry = e.entry; return *this; } + + Addr _pfn() const { return (entry >> 32) & 0xffffffff; } + Addr _sw() const { return (entry >> 16) & 0xffff; } + int _rsv0() const { return (entry >> 14) & 0x3; } + bool _uwe() const { return (entry >> 13) & 0x1; } + bool _kwe() const { return (entry >> 12) & 0x1; } + int _rsv1() const { return (entry >> 10) & 0x3; } + bool _ure() const { return (entry >> 9) & 0x1; } + bool _kre() const { return (entry >> 8) & 0x1; } + bool _nomb() const { return (entry >> 7) & 0x1; } + int _gh() const { return (entry >> 5) & 0x3; } + bool _asm_() const { return (entry >> 4) & 0x1; } + bool _foe() const { return (entry >> 3) & 0x1; } + bool _fow() const { return (entry >> 2) & 0x1; } + bool _for() const { return (entry >> 1) & 0x1; } + bool valid() const { return (entry >> 0) & 0x1; } + + Addr paddr() const { return _pfn() << PageShift; } +}; + +// ITB/DTB table entry +struct TlbEntry +{ + Addr tag; // virtual page number tag + Addr ppn; // physical page number + uint8_t xre; // read permissions - VMEM_PERM_* mask + uint8_t xwe; // write permissions - VMEM_PERM_* mask + uint8_t asn; // address space number + bool asma; // address space match + bool fonr; // fault on read + bool fonw; // fault on write + bool valid; // valid page table entry + + + //Construct an entry that maps to physical address addr. + TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr) { - PageTableEntry(uint64_t e) : entry(e) {} - uint64_t entry; - operator uint64_t() const { return entry; } - const PageTableEntry &operator=(uint64_t e) { entry = e; return *this; } - const PageTableEntry &operator=(const PageTableEntry &e) - { entry = e.entry; return *this; } - - Addr _pfn() const { return (entry >> 32) & 0xffffffff; } - Addr _sw() const { return (entry >> 16) & 0xffff; } - int _rsv0() const { return (entry >> 14) & 0x3; } - bool _uwe() const { return (entry >> 13) & 0x1; } - bool _kwe() const { return (entry >> 12) & 0x1; } - int _rsv1() const { return (entry >> 10) & 0x3; } - bool _ure() const { return (entry >> 9) & 0x1; } - bool _kre() const { return (entry >> 8) & 0x1; } - bool _nomb() const { return (entry >> 7) & 0x1; } - int _gh() const { return (entry >> 5) & 0x3; } - bool _asm_() const { return (entry >> 4) & 0x1; } - bool _foe() const { return (entry >> 3) & 0x1; } - bool _fow() const { return (entry >> 2) & 0x1; } - bool _for() const { return (entry >> 1) & 0x1; } - bool valid() const { return (entry >> 0) & 0x1; } - - Addr paddr() const { return _pfn() << PageShift; } - }; - - // ITB/DTB table entry - struct TlbEntry + VAddr vaddr(_vaddr); + VAddr paddr(_paddr); + tag = vaddr.vpn(); + ppn = paddr.vpn(); + xre = 15; + xwe = 15; + asn = _asn; + asma = false; + fonr = false; + fonw = false; + valid = true; + } + + TlbEntry() + {} + + Addr + pageStart() { - //Construct an entry that maps to physical address addr. - TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr) - { - VAddr vaddr(_vaddr); - VAddr paddr(_paddr); - tag = vaddr.vpn(); - ppn = paddr.vpn(); - xre = 15; - xwe = 15; - asn = _asn; - asma = false; - fonr = false; - fonw = false; - valid = true; - } - TlbEntry() - {} - - Addr tag; // virtual page number tag - Addr ppn; // physical page number - uint8_t xre; // read permissions - VMEM_PERM_* mask - uint8_t xwe; // write permissions - VMEM_PERM_* mask - uint8_t asn; // address space number - bool asma; // address space match - bool fonr; // fault on read - bool fonw; // fault on write - bool valid; // valid page table entry - - Addr pageStart() - { - return ppn << PageShift; - } - - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); - }; + return ppn << PageShift; + } + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); }; + +} // namespace AlphaISA + #endif // __ARCH_ALPHA_PAGETABLE_H__ diff --git a/src/arch/alpha/predecoder.hh b/src/arch/alpha/predecoder.hh index 725b35b9d..5502342e1 100644 --- a/src/arch/alpha/predecoder.hh +++ b/src/arch/alpha/predecoder.hh @@ -38,62 +38,72 @@ class ThreadContext; -namespace AlphaISA +namespace AlphaISA { + +class Predecoder { - class Predecoder + protected: + ThreadContext *tc; + + // The extended machine instruction being generated + ExtMachInst ext_inst; + + public: + Predecoder(ThreadContext * _tc) + : tc(_tc) + {} + + ThreadContext * + getTC() { - protected: - ThreadContext * tc; - //The extended machine instruction being generated - ExtMachInst ext_inst; - - public: - Predecoder(ThreadContext * _tc) : tc(_tc) - {} - - ThreadContext * getTC() - { - return tc; - } - - void setTC(ThreadContext * _tc) - { - tc = _tc; - } - - void process() - { - } - - void reset() - {} - - //Use this to give data to the predecoder. This should be used - //when there is control flow. - void moreBytes(Addr pc, Addr fetchPC, MachInst inst) - { - ext_inst = inst; + return tc; + } + + void + setTC(ThreadContext * _tc) + { + tc = _tc; + } + + void + process() + { } + + void + reset() + { } + + // Use this to give data to the predecoder. This should be used + // when there is control flow. + void + moreBytes(Addr pc, Addr fetchPC, MachInst inst) + { + ext_inst = inst; #if FULL_SYSTEM - ext_inst|=(static_cast(pc & 0x1) << 32); + ext_inst |= (static_cast(pc & 0x1) << 32); #endif - } - - bool needMoreBytes() - { - return true; - } - - bool extMachInstReady() - { - return true; - } - - //This returns a constant reference to the ExtMachInst to avoid a copy - const ExtMachInst & getExtMachInst() - { - return ext_inst; - } - }; + } + + bool + needMoreBytes() + { + return true; + } + + bool + extMachInstReady() + { + return true; + } + + // This returns a constant reference to the ExtMachInst to avoid a copy + const ExtMachInst & + getExtMachInst() + { + return ext_inst; + } }; +} // namespace AlphaISA + #endif // __ARCH_ALPHA_PREDECODER_HH__ diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc index c2d23ecdd..380e0e18e 100644 --- a/src/arch/alpha/process.cc +++ b/src/arch/alpha/process.cc @@ -36,12 +36,11 @@ #include "cpu/thread_context.hh" #include "sim/system.hh" - using namespace AlphaISA; using namespace std; -AlphaLiveProcess::AlphaLiveProcess(LiveProcessParams * params, - ObjectFile *objFile) +AlphaLiveProcess::AlphaLiveProcess(LiveProcessParams *params, + ObjectFile *objFile) : LiveProcess(params, objFile) { brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize(); @@ -77,4 +76,3 @@ AlphaLiveProcess::startup() threadContexts[0]->setMiscRegNoEffect(IPR_DTB_ASN, M5_pid << 57); } - diff --git a/src/arch/alpha/process.hh b/src/arch/alpha/process.hh index c66b97d23..0aeeb25db 100644 --- a/src/arch/alpha/process.hh +++ b/src/arch/alpha/process.hh @@ -29,24 +29,20 @@ * Ali Saidi */ -#ifndef __ALPHA_PROCESS_HH__ -#define __ALPHA_PROCESS_HH__ +#ifndef __ARCH_ALPHA_PROCESS_HH__ +#define __ARCH_ALPHA_PROCESS_HH__ -#include -#include #include "sim/process.hh" class ObjectFile; class System; - class AlphaLiveProcess : public LiveProcess { protected: - AlphaLiveProcess(LiveProcessParams * params, ObjectFile *objFile); + AlphaLiveProcess(LiveProcessParams *params, ObjectFile *objFile); void startup(); }; - -#endif // __ALPHA_PROCESS_HH__ +#endif // __ARCH_ALPHA_PROCESS_HH__ diff --git a/src/arch/alpha/regfile.cc b/src/arch/alpha/regfile.cc index e617b00ae..cd648844f 100644 --- a/src/arch/alpha/regfile.cc +++ b/src/arch/alpha/regfile.cc @@ -33,67 +33,66 @@ #include "arch/alpha/regfile.hh" #include "cpu/thread_context.hh" -namespace AlphaISA +namespace AlphaISA { + +void +RegFile::serialize(std::ostream &os) { - void - RegFile::serialize(std::ostream &os) - { - intRegFile.serialize(os); - floatRegFile.serialize(os); - miscRegFile.serialize(os); - SERIALIZE_SCALAR(pc); - SERIALIZE_SCALAR(npc); + intRegFile.serialize(os); + floatRegFile.serialize(os); + miscRegFile.serialize(os); + SERIALIZE_SCALAR(pc); + SERIALIZE_SCALAR(npc); #if FULL_SYSTEM - SERIALIZE_SCALAR(intrflag); + SERIALIZE_SCALAR(intrflag); #endif - } +} - void - RegFile::unserialize(Checkpoint *cp, const std::string §ion) - { - intRegFile.unserialize(cp, section); - floatRegFile.unserialize(cp, section); - miscRegFile.unserialize(cp, section); - UNSERIALIZE_SCALAR(pc); - UNSERIALIZE_SCALAR(npc); +void +RegFile::unserialize(Checkpoint *cp, const std::string §ion) +{ + intRegFile.unserialize(cp, section); + floatRegFile.unserialize(cp, section); + miscRegFile.unserialize(cp, section); + UNSERIALIZE_SCALAR(pc); + UNSERIALIZE_SCALAR(npc); #if FULL_SYSTEM - UNSERIALIZE_SCALAR(intrflag); + UNSERIALIZE_SCALAR(intrflag); #endif - } +} - void - copyRegs(ThreadContext *src, ThreadContext *dest) - { - // First loop through the integer registers. - for (int i = 0; i < NumIntRegs; ++i) { - dest->setIntReg(i, src->readIntReg(i)); - } +void +copyRegs(ThreadContext *src, ThreadContext *dest) +{ + // First loop through the integer registers. + for (int i = 0; i < NumIntRegs; ++i) + dest->setIntReg(i, src->readIntReg(i)); - // Then loop through the floating point registers. - for (int i = 0; i < NumFloatRegs; ++i) { - dest->setFloatRegBits(i, src->readFloatRegBits(i)); - } + // Then loop through the floating point registers. + for (int i = 0; i < NumFloatRegs; ++i) + dest->setFloatRegBits(i, src->readFloatRegBits(i)); - // Copy misc. registers - copyMiscRegs(src, dest); + // Copy misc. registers + copyMiscRegs(src, dest); - // Lastly copy PC/NPC - dest->setPC(src->readPC()); - dest->setNextPC(src->readNextPC()); - } + // Lastly copy PC/NPC + dest->setPC(src->readPC()); + dest->setNextPC(src->readNextPC()); +} - void - copyMiscRegs(ThreadContext *src, ThreadContext *dest) - { - dest->setMiscRegNoEffect(MISCREG_FPCR, - src->readMiscRegNoEffect(MISCREG_FPCR)); - dest->setMiscRegNoEffect(MISCREG_UNIQ, - src->readMiscRegNoEffect(MISCREG_UNIQ)); - dest->setMiscRegNoEffect(MISCREG_LOCKFLAG, - src->readMiscRegNoEffect(MISCREG_LOCKFLAG)); - dest->setMiscRegNoEffect(MISCREG_LOCKADDR, - src->readMiscRegNoEffect(MISCREG_LOCKADDR)); +void +copyMiscRegs(ThreadContext *src, ThreadContext *dest) +{ + dest->setMiscRegNoEffect(MISCREG_FPCR, + src->readMiscRegNoEffect(MISCREG_FPCR)); + dest->setMiscRegNoEffect(MISCREG_UNIQ, + src->readMiscRegNoEffect(MISCREG_UNIQ)); + dest->setMiscRegNoEffect(MISCREG_LOCKFLAG, + src->readMiscRegNoEffect(MISCREG_LOCKFLAG)); + dest->setMiscRegNoEffect(MISCREG_LOCKADDR, + src->readMiscRegNoEffect(MISCREG_LOCKADDR)); - copyIprs(src, dest); - } + copyIprs(src, dest); } + +} // namespace AlphaISA diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh index 0c1f07bdd..c9fa8a91b 100644 --- a/src/arch/alpha/regfile.hh +++ b/src/arch/alpha/regfile.hh @@ -45,161 +45,190 @@ class Checkpoint; class ThreadContext; -namespace AlphaISA -{ - - class RegFile { +namespace AlphaISA { - protected: - Addr pc; // program counter - Addr npc; // next-cycle program counter - Addr nnpc; +class RegFile { + protected: + Addr pc; // program counter + Addr npc; // next-cycle program counter + Addr nnpc; // next next-cycle program counter - public: - Addr readPC() - { - return pc; - } - - void setPC(Addr val) - { - pc = val; - } + public: + Addr + readPC() + { + return pc; + } - Addr readNextPC() - { - return npc; - } + void + setPC(Addr val) + { + pc = val; + } - void setNextPC(Addr val) - { - npc = val; - } + Addr + readNextPC() + { + return npc; + } - Addr readNextNPC() - { - return npc + sizeof(MachInst); - } + void + setNextPC(Addr val) + { + npc = val; + } - void setNextNPC(Addr val) - { } + Addr + readNextNPC() + { + return npc + sizeof(MachInst); + } - protected: - IntRegFile intRegFile; // (signed) integer register file - FloatRegFile floatRegFile; // floating point register file - MiscRegFile miscRegFile; // control register file + void + setNextNPC(Addr val) + { } - public: + protected: + IntRegFile intRegFile; // (signed) integer register file + FloatRegFile floatRegFile; // floating point register file + MiscRegFile miscRegFile; // control register file + public: #if FULL_SYSTEM - int intrflag; // interrupt flag - inline int instAsid() - { return miscRegFile.getInstAsid(); } - inline int dataAsid() - { return miscRegFile.getDataAsid(); } -#endif // FULL_SYSTEM + int intrflag; // interrupt flag - void clear() - { - intRegFile.clear(); - floatRegFile.clear(); - miscRegFile.clear(); - } - - MiscReg readMiscRegNoEffect(int miscReg) - { - return miscRegFile.readRegNoEffect(miscReg); - } + int + instAsid() + { + return miscRegFile.getInstAsid(); + } - MiscReg readMiscReg(int miscReg, ThreadContext *tc) - { - return miscRegFile.readReg(miscReg, tc); - } + int + dataAsid() + { + return miscRegFile.getDataAsid(); + } +#endif // FULL_SYSTEM - void setMiscRegNoEffect(int miscReg, const MiscReg &val) - { - miscRegFile.setRegNoEffect(miscReg, val); - } + void + clear() + { + intRegFile.clear(); + floatRegFile.clear(); + miscRegFile.clear(); + } - void setMiscReg(int miscReg, const MiscReg &val, - ThreadContext * tc) - { - miscRegFile.setReg(miscReg, val, tc); - } + MiscReg + readMiscRegNoEffect(int miscReg) + { + return miscRegFile.readRegNoEffect(miscReg); + } - FloatReg readFloatReg(int floatReg) - { - return floatRegFile.d[floatReg]; - } + MiscReg + readMiscReg(int miscReg, ThreadContext *tc) + { + return miscRegFile.readReg(miscReg, tc); + } - FloatReg readFloatReg(int floatReg, int width) - { - return readFloatReg(floatReg); - } + void + setMiscRegNoEffect(int miscReg, const MiscReg &val) + { + miscRegFile.setRegNoEffect(miscReg, val); + } - FloatRegBits readFloatRegBits(int floatReg) - { - return floatRegFile.q[floatReg]; - } + void + setMiscReg(int miscReg, const MiscReg &val, ThreadContext *tc) + { + miscRegFile.setReg(miscReg, val, tc); + } - FloatRegBits readFloatRegBits(int floatReg, int width) - { - return readFloatRegBits(floatReg); - } + FloatReg + readFloatReg(int floatReg) + { + return floatRegFile.d[floatReg]; + } - void setFloatReg(int floatReg, const FloatReg &val) - { - floatRegFile.d[floatReg] = val; - } + FloatReg + readFloatReg(int floatReg, int width) + { + return readFloatReg(floatReg); + } - void setFloatReg(int floatReg, const FloatReg &val, int width) - { - setFloatReg(floatReg, val); - } + FloatRegBits + readFloatRegBits(int floatReg) + { + return floatRegFile.q[floatReg]; + } - void setFloatRegBits(int floatReg, const FloatRegBits &val) - { - floatRegFile.q[floatReg] = val; - } + FloatRegBits + readFloatRegBits(int floatReg, int width) + { + return readFloatRegBits(floatReg); + } - void setFloatRegBits(int floatReg, const FloatRegBits &val, int width) - { - setFloatRegBits(floatReg, val); - } + void + setFloatReg(int floatReg, const FloatReg &val) + { + floatRegFile.d[floatReg] = val; + } - IntReg readIntReg(int intReg) - { - return intRegFile.readReg(intReg); - } + void + setFloatReg(int floatReg, const FloatReg &val, int width) + { + setFloatReg(floatReg, val); + } - void setIntReg(int intReg, const IntReg &val) - { - intRegFile.setReg(intReg, val); - } + void + setFloatRegBits(int floatReg, const FloatRegBits &val) + { + floatRegFile.q[floatReg] = val; + } - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); + void + setFloatRegBits(int floatReg, const FloatRegBits &val, int width) + { + setFloatRegBits(floatReg, val); + } - void changeContext(RegContextParam param, RegContextVal val) - { - //This would be an alternative place to call/implement - //the swapPALShadow function - } - }; + IntReg + readIntReg(int intReg) + { + return intRegFile.readReg(intReg); + } - static inline int flattenIntIndex(ThreadContext * tc, int reg) + void + setIntReg(int intReg, const IntReg &val) { - return reg; + intRegFile.setReg(intReg, val); } - static inline int flattenFloatIndex(ThreadContext * tc, int reg) + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); + + void + changeContext(RegContextParam param, RegContextVal val) { - return reg; + //This would be an alternative place to call/implement + //the swapPALShadow function } +}; + +static inline int +flattenIntIndex(ThreadContext * tc, int reg) +{ + return reg; +} + +static inline int +flattenFloatIndex(ThreadContext * tc, int reg) +{ + return reg; +} + +void copyRegs(ThreadContext *src, ThreadContext *dest); - void copyRegs(ThreadContext *src, ThreadContext *dest); +void copyMiscRegs(ThreadContext *src, ThreadContext *dest); - void copyMiscRegs(ThreadContext *src, ThreadContext *dest); } // namespace AlphaISA -#endif +#endif // __ARCH_ALPHA_REGFILE_HH__ diff --git a/src/arch/alpha/remote_gdb.cc b/src/arch/alpha/remote_gdb.cc index 22a1f5224..c47293b98 100644 --- a/src/arch/alpha/remote_gdb.cc +++ b/src/arch/alpha/remote_gdb.cc @@ -117,9 +117,9 @@ */ #include +#include #include -#include #include "config/full_system.hh" #if FULL_SYSTEM @@ -142,17 +142,15 @@ using namespace std; using namespace AlphaISA; -RemoteGDB::RemoteGDB(System *_system, ThreadContext *c) - : BaseRemoteGDB(_system, c, KGDB_NUMREGS) +RemoteGDB::RemoteGDB(System *_system, ThreadContext *tc) + : BaseRemoteGDB(_system, tc, KGDB_NUMREGS) { memset(gdbregs.regs, 0, gdbregs.bytes()); } -/////////////////////////////////////////////////////////// -// RemoteGDB::acc -// -// Determine if the mapping at va..(va+len) is valid. -// +/* + * Determine if the mapping at va..(va+len) is valid. + */ bool RemoteGDB::acc(Addr va, size_t len) { @@ -177,18 +175,20 @@ RemoteGDB::acc(Addr va, size_t len) } } - /** - * This code says that all accesses to palcode (instruction and data) - * are valid since there isn't a va->pa mapping because palcode is - * accessed physically. At some point this should probably be cleaned up - * but there is no easy way to do it. - */ + /** + * This code says that all accesses to palcode (instruction + * and data) are valid since there isn't a va->pa mapping + * because palcode is accessed physically. At some point this + * should probably be cleaned up but there is no easy way to + * do it. + */ if (PcPAL(va) || va < 0x10000) return true; Addr ptbr = context->readMiscRegNoEffect(IPR_PALtemp20); - PageTableEntry pte = kernel_pte_lookup(context->getPhysPort(), ptbr, va); + PageTableEntry pte = + kernel_pte_lookup(context->getPhysPort(), ptbr, va); if (!pte.valid()) { DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va); return false; @@ -201,11 +201,10 @@ RemoteGDB::acc(Addr va, size_t len) #endif } -/////////////////////////////////////////////////////////// -// RemoteGDB::getregs -// -// Translate the kernel debugger register format into -// the GDB register format. +/* + * Translate the kernel debugger register format into the GDB register + * format. + */ void RemoteGDB::getregs() { @@ -231,12 +230,10 @@ RemoteGDB::getregs() #endif } -/////////////////////////////////////////////////////////// -// RemoteGDB::setregs -// -// Translate the GDB register format into the kernel -// debugger register format. -// +/* + * Translate the GDB register format into the kernel debugger register + * format. + */ void RemoteGDB::setregs() { diff --git a/src/arch/alpha/remote_gdb.hh b/src/arch/alpha/remote_gdb.hh index 7bef183c3..43d0580d8 100644 --- a/src/arch/alpha/remote_gdb.hh +++ b/src/arch/alpha/remote_gdb.hh @@ -44,31 +44,29 @@ class System; class ThreadContext; class PhysicalMemory; -namespace AlphaISA -{ - class RemoteGDB : public BaseRemoteGDB - { - protected: - // Machine memory - bool write(Addr addr, size_t size, const char *data); +namespace AlphaISA { - public: - RemoteGDB(System *system, ThreadContext *context); +class RemoteGDB : public BaseRemoteGDB +{ + protected: + Addr notTakenBkpt; + Addr takenBkpt; - bool acc(Addr addr, size_t len); + protected: + void getregs(); + void setregs(); - protected: - void getregs(); - void setregs(); + void clearSingleStep(); + void setSingleStep(); - void clearSingleStep(); - void setSingleStep(); + // Machine memory + bool acc(Addr addr, size_t len); + bool write(Addr addr, size_t size, const char *data); - protected: + public: + RemoteGDB(System *system, ThreadContext *context); +}; - Addr notTakenBkpt; - Addr takenBkpt; - }; -} +} // namespace AlphaISA -#endif /* __ARCH_ALPHA_REMOTE_GDB_H__ */ +#endif // __ARCH_ALPHA_REMOTE_GDB_HH__ diff --git a/src/arch/alpha/stacktrace.cc b/src/arch/alpha/stacktrace.cc index a29a4eb4d..1b5a9be34 100644 --- a/src/arch/alpha/stacktrace.cc +++ b/src/arch/alpha/stacktrace.cc @@ -41,326 +41,326 @@ using namespace std; -namespace AlphaISA +namespace AlphaISA { + +ProcessInfo::ProcessInfo(ThreadContext *_tc) + : tc(_tc) { - ProcessInfo::ProcessInfo(ThreadContext *_tc) - : tc(_tc) - { - Addr addr = 0; + Addr addr = 0; + VirtualPort *vp = tc->getVirtPort(); + SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; - VirtualPort *vp; + if (!symtab->findAddress("thread_info_size", addr)) + panic("thread info not compiled into kernel\n"); + thread_info_size = vp->readGtoH(addr); - vp = tc->getVirtPort(); + if (!symtab->findAddress("task_struct_size", addr)) + panic("thread info not compiled into kernel\n"); + task_struct_size = vp->readGtoH(addr); - if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr)) - panic("thread info not compiled into kernel\n"); - thread_info_size = vp->readGtoH(addr); + if (!symtab->findAddress("thread_info_task", addr)) + panic("thread info not compiled into kernel\n"); + task_off = vp->readGtoH(addr); - if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr)) - panic("thread info not compiled into kernel\n"); - task_struct_size = vp->readGtoH(addr); + if (!symtab->findAddress("task_struct_pid", addr)) + panic("thread info not compiled into kernel\n"); + pid_off = vp->readGtoH(addr); - if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr)) - panic("thread info not compiled into kernel\n"); - task_off = vp->readGtoH(addr); + if (!symtab->findAddress("task_struct_comm", addr)) + panic("thread info not compiled into kernel\n"); + name_off = vp->readGtoH(addr); +} - if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr)) - panic("thread info not compiled into kernel\n"); - pid_off = vp->readGtoH(addr); +Addr +ProcessInfo::task(Addr ksp) const +{ + Addr base = ksp & ~0x3fff; + if (base == ULL(0xfffffc0000000000)) + return 0; - if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr)) - panic("thread info not compiled into kernel\n"); - name_off = vp->readGtoH(addr); - } + Addr tsk; - Addr - ProcessInfo::task(Addr ksp) const - { - Addr base = ksp & ~0x3fff; - if (base == ULL(0xfffffc0000000000)) - return 0; + VirtualPort *vp; - Addr tsk; + vp = tc->getVirtPort(); + tsk = vp->readGtoH(base + task_off); - VirtualPort *vp; + return tsk; +} - vp = tc->getVirtPort(); - tsk = vp->readGtoH(base + task_off); +int +ProcessInfo::pid(Addr ksp) const +{ + Addr task = this->task(ksp); + if (!task) + return -1; - return tsk; - } + uint16_t pd; - int - ProcessInfo::pid(Addr ksp) const - { - Addr task = this->task(ksp); - if (!task) - return -1; + VirtualPort *vp; - uint16_t pd; + vp = tc->getVirtPort(); + pd = vp->readGtoH(task + pid_off); - VirtualPort *vp; + return pd; +} - vp = tc->getVirtPort(); - pd = vp->readGtoH(task + pid_off); +string +ProcessInfo::name(Addr ksp) const +{ + Addr task = this->task(ksp); + if (!task) + return "console"; - return pd; - } + char comm[256]; + CopyStringOut(tc, comm, task + name_off, sizeof(comm)); + if (!comm[0]) + return "startup"; - string - ProcessInfo::name(Addr ksp) const - { - Addr task = this->task(ksp); - if (!task) - return "console"; + return comm; +} - char comm[256]; - CopyStringOut(tc, comm, task + name_off, sizeof(comm)); - if (!comm[0]) - return "startup"; +StackTrace::StackTrace() + : tc(0), stack(64) +{ +} - return comm; - } +StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst) + : tc(0), stack(64) +{ + trace(_tc, inst); +} - StackTrace::StackTrace() - : tc(0), stack(64) - { - } +StackTrace::~StackTrace() +{ +} - StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst) - : tc(0), stack(64) - { - trace(_tc, inst); - } +void +StackTrace::trace(ThreadContext *_tc, bool is_call) +{ + tc = _tc; - StackTrace::~StackTrace() - { - } + System *sys = tc->getSystemPtr(); - void - StackTrace::trace(ThreadContext *_tc, bool is_call) - { - tc = _tc; + bool usermode = + (tc->readMiscRegNoEffect(IPR_DTB_CM) & 0x18) != 0; - bool usermode = (tc->readMiscRegNoEffect(IPR_DTB_CM) & 0x18) != 0; + Addr pc = tc->readNextPC(); + bool kernel = sys->kernelStart <= pc && pc <= sys->kernelEnd; - Addr pc = tc->readNextPC(); - bool kernel = tc->getSystemPtr()->kernelStart <= pc && - pc <= tc->getSystemPtr()->kernelEnd; + if (usermode) { + stack.push_back(user); + return; + } - if (usermode) { - stack.push_back(user); - return; - } + if (!kernel) { + stack.push_back(console); + return; + } - if (!kernel) { - stack.push_back(console); - return; - } + SymbolTable *symtab = sys->kernelSymtab; + Addr ksp = tc->readIntReg(StackPointerReg); + Addr bottom = ksp & ~0x3fff; - SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; - Addr ksp = tc->readIntReg(StackPointerReg); - Addr bottom = ksp & ~0x3fff; + if (is_call) { Addr addr; + if (!symtab->findNearestAddr(pc, addr)) + panic("could not find address %#x", pc); - if (is_call) { - if (!symtab->findNearestAddr(pc, addr)) - panic("could not find address %#x", pc); - - stack.push_back(addr); - pc = tc->readPC(); - } + stack.push_back(addr); + pc = tc->readPC(); + } - Addr ra; - int size; + while (ksp > bottom) { + Addr addr; + if (!symtab->findNearestAddr(pc, addr)) + panic("could not find symbol for pc=%#x", pc); + assert(pc >= addr && "symbol botch: callpc < func"); - while (ksp > bottom) { - if (!symtab->findNearestAddr(pc, addr)) - panic("could not find symbol for pc=%#x", pc); - assert(pc >= addr && "symbol botch: callpc < func"); + stack.push_back(addr); - stack.push_back(addr); + if (isEntry(addr)) + return; - if (isEntry(addr)) + Addr ra; + int size; + if (decodePrologue(ksp, pc, addr, size, ra)) { + if (!ra) return; - if (decodePrologue(ksp, pc, addr, size, ra)) { - if (!ra) - return; - - if (size <= 0) { - stack.push_back(unknown); - return; - } - - pc = ra; - ksp += size; - } else { + if (size <= 0) { stack.push_back(unknown); return; } - bool kernel = tc->getSystemPtr()->kernelStart <= pc && - pc <= tc->getSystemPtr()->kernelEnd; - if (!kernel) - return; - - if (stack.size() >= 1000) - panic("unwinding too far"); + pc = ra; + ksp += size; + } else { + stack.push_back(unknown); + return; } - panic("unwinding too far"); + bool kernel = sys->kernelStart <= pc && pc <= sys->kernelEnd; + if (!kernel) + return; + + if (stack.size() >= 1000) + panic("unwinding too far"); } - bool - StackTrace::isEntry(Addr addr) - { - if (addr == tc->readMiscRegNoEffect(IPR_PALtemp12)) - return true; + panic("unwinding too far"); +} - if (addr == tc->readMiscRegNoEffect(IPR_PALtemp7)) - return true; +bool +StackTrace::isEntry(Addr addr) +{ + if (addr == tc->readMiscRegNoEffect(IPR_PALtemp12)) + return true; - if (addr == tc->readMiscRegNoEffect(IPR_PALtemp11)) - return true; + if (addr == tc->readMiscRegNoEffect(IPR_PALtemp7)) + return true; - if (addr == tc->readMiscRegNoEffect(IPR_PALtemp21)) - return true; + if (addr == tc->readMiscRegNoEffect(IPR_PALtemp11)) + return true; - if (addr == tc->readMiscRegNoEffect(IPR_PALtemp9)) - return true; + if (addr == tc->readMiscRegNoEffect(IPR_PALtemp21)) + return true; - if (addr == tc->readMiscRegNoEffect(IPR_PALtemp2)) - return true; + if (addr == tc->readMiscRegNoEffect(IPR_PALtemp9)) + return true; - return false; - } + if (addr == tc->readMiscRegNoEffect(IPR_PALtemp2)) + return true; - bool - StackTrace::decodeStack(MachInst inst, int &disp) - { - // lda $sp, -disp($sp) - // - // Opcode<31:26> == 0x08 - // RA<25:21> == 30 - // RB<20:16> == 30 - // Disp<15:0> - const MachInst mem_mask = 0xffff0000; - const MachInst lda_pattern = 0x23de0000; - const MachInst lda_disp_mask = 0x0000ffff; - - // subq $sp, disp, $sp - // addq $sp, disp, $sp - // - // Opcode<31:26> == 0x10 - // RA<25:21> == 30 - // Lit<20:13> - // One<12> = 1 - // Func<11:5> == 0x20 (addq) - // Func<11:5> == 0x29 (subq) - // RC<4:0> == 30 - const MachInst intop_mask = 0xffe01fff; - const MachInst addq_pattern = 0x43c0141e; - const MachInst subq_pattern = 0x43c0153e; - const MachInst intop_disp_mask = 0x001fe000; - const int intop_disp_shift = 13; - - if ((inst & mem_mask) == lda_pattern) - disp = -sext<16>(inst & lda_disp_mask); - else if ((inst & intop_mask) == addq_pattern) - disp = -int((inst & intop_disp_mask) >> intop_disp_shift); - else if ((inst & intop_mask) == subq_pattern) - disp = int((inst & intop_disp_mask) >> intop_disp_shift); - else - return false; + return false; +} - return true; - } +bool +StackTrace::decodeStack(MachInst inst, int &disp) +{ + // lda $sp, -disp($sp) + // + // Opcode<31:26> == 0x08 + // RA<25:21> == 30 + // RB<20:16> == 30 + // Disp<15:0> + const MachInst mem_mask = 0xffff0000; + const MachInst lda_pattern = 0x23de0000; + const MachInst lda_disp_mask = 0x0000ffff; + + // subq $sp, disp, $sp + // addq $sp, disp, $sp + // + // Opcode<31:26> == 0x10 + // RA<25:21> == 30 + // Lit<20:13> + // One<12> = 1 + // Func<11:5> == 0x20 (addq) + // Func<11:5> == 0x29 (subq) + // RC<4:0> == 30 + const MachInst intop_mask = 0xffe01fff; + const MachInst addq_pattern = 0x43c0141e; + const MachInst subq_pattern = 0x43c0153e; + const MachInst intop_disp_mask = 0x001fe000; + const int intop_disp_shift = 13; + + if ((inst & mem_mask) == lda_pattern) + disp = -sext<16>(inst & lda_disp_mask); + else if ((inst & intop_mask) == addq_pattern) + disp = -int((inst & intop_disp_mask) >> intop_disp_shift); + else if ((inst & intop_mask) == subq_pattern) + disp = int((inst & intop_disp_mask) >> intop_disp_shift); + else + return false; - bool - StackTrace::decodeSave(MachInst inst, int ®, int &disp) - { - // lda $stq, disp($sp) - // - // Opcode<31:26> == 0x08 - // RA<25:21> == ? - // RB<20:16> == 30 - // Disp<15:0> - const MachInst stq_mask = 0xfc1f0000; - const MachInst stq_pattern = 0xb41e0000; - const MachInst stq_disp_mask = 0x0000ffff; - const MachInst reg_mask = 0x03e00000; - const int reg_shift = 21; - - if ((inst & stq_mask) == stq_pattern) { - reg = (inst & reg_mask) >> reg_shift; - disp = sext<16>(inst & stq_disp_mask); - } else { - return false; - } + return true; +} - return true; +bool +StackTrace::decodeSave(MachInst inst, int ®, int &disp) +{ + // lda $stq, disp($sp) + // + // Opcode<31:26> == 0x08 + // RA<25:21> == ? + // RB<20:16> == 30 + // Disp<15:0> + const MachInst stq_mask = 0xfc1f0000; + const MachInst stq_pattern = 0xb41e0000; + const MachInst stq_disp_mask = 0x0000ffff; + const MachInst reg_mask = 0x03e00000; + const int reg_shift = 21; + + if ((inst & stq_mask) == stq_pattern) { + reg = (inst & reg_mask) >> reg_shift; + disp = sext<16>(inst & stq_disp_mask); + } else { + return false; } - /* - * Decode the function prologue for the function we're in, and note - * which registers are stored where, and how large the stack frame is. - */ - bool - StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, - int &size, Addr &ra) - { - size = 0; - ra = 0; - - for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) { - MachInst inst; - CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst)); - - int reg, disp; - if (decodeStack(inst, disp)) { - if (size) { - // panic("decoding frame size again"); - return true; - } - size += disp; - } else if (decodeSave(inst, reg, disp)) { - if (!ra && reg == ReturnAddressReg) { - CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr)); - if (!ra) { - // panic("no return address value pc=%#x\n", pc); - return false; - } + return true; +} + +/* + * Decode the function prologue for the function we're in, and note + * which registers are stored where, and how large the stack frame is. + */ +bool +StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, int &size, + Addr &ra) +{ + size = 0; + ra = 0; + + for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) { + MachInst inst; + CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst)); + + int reg, disp; + if (decodeStack(inst, disp)) { + if (size) { + // panic("decoding frame size again"); + return true; + } + size += disp; + } else if (decodeSave(inst, reg, disp)) { + if (!ra && reg == ReturnAddressReg) { + CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr)); + if (!ra) { + // panic("no return address value pc=%#x\n", pc); + return false; } } } - - return true; } + return true; +} + #if TRACING_ON - void - StackTrace::dump() - { - StringWrap name(tc->getCpuPtr()->name()); - SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; - - DPRINTFN("------ Stack ------\n"); - - string symbol; - for (int i = 0, size = stack.size(); i < size; ++i) { - Addr addr = stack[size - i - 1]; - if (addr == user) - symbol = "user"; - else if (addr == console) - symbol = "console"; - else if (addr == unknown) - symbol = "unknown"; - else - symtab->findSymbol(addr, symbol); - - DPRINTFN("%#x: %s\n", addr, symbol); - } +void +StackTrace::dump() +{ + StringWrap name(tc->getCpuPtr()->name()); + SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; + + DPRINTFN("------ Stack ------\n"); + + string symbol; + for (int i = 0, size = stack.size(); i < size; ++i) { + Addr addr = stack[size - i - 1]; + if (addr == user) + symbol = "user"; + else if (addr == console) + symbol = "console"; + else if (addr == unknown) + symbol = "unknown"; + else + symtab->findSymbol(addr, symbol); + + DPRINTFN("%#x: %s\n", addr, symbol); } -#endif } +#endif + +} // namespace AlphaISA diff --git a/src/arch/alpha/stacktrace.hh b/src/arch/alpha/stacktrace.hh index 39fd3d286..db42c4399 100644 --- a/src/arch/alpha/stacktrace.hh +++ b/src/arch/alpha/stacktrace.hh @@ -36,88 +36,90 @@ class ThreadContext; -namespace AlphaISA -{ - class StackTrace; +namespace AlphaISA { - class ProcessInfo - { - private: - ThreadContext *tc; +class StackTrace; + +class ProcessInfo +{ + private: + ThreadContext *tc; - int thread_info_size; - int task_struct_size; - int task_off; - int pid_off; - int name_off; + int thread_info_size; + int task_struct_size; + int task_off; + int pid_off; + int name_off; - public: - ProcessInfo(ThreadContext *_tc); + public: + ProcessInfo(ThreadContext *_tc); - Addr task(Addr ksp) const; - int pid(Addr ksp) const; - std::string name(Addr ksp) const; - }; + Addr task(Addr ksp) const; + int pid(Addr ksp) const; + std::string name(Addr ksp) const; +}; - class StackTrace - { - private: - ThreadContext *tc; - std::vector stack; +class StackTrace +{ + private: + ThreadContext *tc; + std::vector stack; - private: - bool isEntry(Addr addr); - bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra); - bool decodeSave(MachInst inst, int ®, int &disp); - bool decodeStack(MachInst inst, int &disp); + private: + bool isEntry(Addr addr); + bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra); + bool decodeSave(MachInst inst, int ®, int &disp); + bool decodeStack(MachInst inst, int &disp); - void trace(ThreadContext *tc, bool is_call); + void trace(ThreadContext *tc, bool is_call); - public: - StackTrace(); - StackTrace(ThreadContext *tc, StaticInstPtr inst); - ~StackTrace(); + public: + StackTrace(); + StackTrace(ThreadContext *tc, StaticInstPtr inst); + ~StackTrace(); - void clear() - { - tc = 0; - stack.clear(); - } + void + clear() + { + tc = 0; + stack.clear(); + } - bool valid() const { return tc != NULL; } - bool trace(ThreadContext *tc, StaticInstPtr inst); + bool valid() const { return tc != NULL; } + bool trace(ThreadContext *tc, StaticInstPtr inst); - public: - const std::vector &getstack() const { return stack; } + public: + const std::vector &getstack() const { return stack; } - static const int user = 1; - static const int console = 2; - static const int unknown = 3; + static const int user = 1; + static const int console = 2; + static const int unknown = 3; #if TRACING_ON - private: - void dump(); + private: + void dump(); - public: - void dprintf() { if (DTRACE(Stack)) dump(); } + public: + void dprintf() { if (DTRACE(Stack)) dump(); } #else - public: - void dprintf() {} + public: + void dprintf() {} #endif - }; +}; - inline bool - StackTrace::trace(ThreadContext *tc, StaticInstPtr inst) - { - if (!inst->isCall() && !inst->isReturn()) - return false; +inline bool +StackTrace::trace(ThreadContext *tc, StaticInstPtr inst) +{ + if (!inst->isCall() && !inst->isReturn()) + return false; - if (valid()) - clear(); + if (valid()) + clear(); - trace(tc, !inst->isReturn()); - return true; - } + trace(tc, !inst->isReturn()); + return true; } +} // namespace AlphaISA + #endif // __ARCH_ALPHA_STACKTRACE_HH__ diff --git a/src/arch/alpha/syscallreturn.hh b/src/arch/alpha/syscallreturn.hh index 47b4ac8c7..776f34fbf 100644 --- a/src/arch/alpha/syscallreturn.hh +++ b/src/arch/alpha/syscallreturn.hh @@ -35,24 +35,25 @@ #include "cpu/thread_context.hh" #include "sim/syscallreturn.hh" -namespace AlphaISA +namespace AlphaISA { + +static inline void +setSyscallReturn(SyscallReturn return_value, ThreadContext *tc) { - static inline void setSyscallReturn(SyscallReturn return_value, - ThreadContext * tc) - { - // check for error condition. Alpha syscall convention is to - // indicate success/failure in reg a3 (r19) and put the - // return value itself in the standard return value reg (v0). - if (return_value.successful()) { - // no error - tc->setIntReg(SyscallSuccessReg, 0); - tc->setIntReg(ReturnValueReg, return_value.value()); - } else { - // got an error, return details - tc->setIntReg(SyscallSuccessReg, (IntReg)-1); - tc->setIntReg(ReturnValueReg, -return_value.value()); - } + // check for error condition. Alpha syscall convention is to + // indicate success/failure in reg a3 (r19) and put the + // return value itself in the standard return value reg (v0). + if (return_value.successful()) { + // no error + tc->setIntReg(SyscallSuccessReg, 0); + tc->setIntReg(ReturnValueReg, return_value.value()); + } else { + // got an error, return details + tc->setIntReg(SyscallSuccessReg, (IntReg)-1); + tc->setIntReg(ReturnValueReg, -return_value.value()); } } -#endif +} // namespace AlphaISA + +#endif // __ARCH_ALPHA_SYSCALLRETURN_HH__ diff --git a/src/arch/alpha/system.cc b/src/arch/alpha/system.cc index 6bff3d798..72d918870 100644 --- a/src/arch/alpha/system.cc +++ b/src/arch/alpha/system.cc @@ -116,7 +116,6 @@ AlphaSystem::AlphaSystem(Params *p) virtPort.write(addr+0x58, data); } else panic("could not find hwrpb\n"); - } AlphaSystem::~AlphaSystem() @@ -175,7 +174,7 @@ AlphaSystem::fixFuncEventAddr(Addr addr) if ((i1 & inst_mask) == gp_ldah_pattern && (i2 & inst_mask) == gp_lda_pattern) { - Addr new_addr = addr + 2* sizeof(MachInst); + Addr new_addr = addr + 2 * sizeof(MachInst); DPRINTF(Loader, "fixFuncEventAddr: %p -> %p", addr, new_addr); return new_addr; } else { @@ -183,15 +182,15 @@ AlphaSystem::fixFuncEventAddr(Addr addr) } } - void AlphaSystem::setAlphaAccess(Addr access) { Addr addr = 0; if (consoleSymtab->findAddress("m5AlphaAccess", addr)) { virtPort.write(addr, htog(Phys2K0Seg(access))); - } else + } else { panic("could not find m5AlphaAccess\n"); + } } void @@ -202,7 +201,6 @@ AlphaSystem::serialize(std::ostream &os) palSymtab->serialize("pal_symtab", os); } - void AlphaSystem::unserialize(Checkpoint *cp, const std::string §ion) { diff --git a/src/arch/alpha/system.hh b/src/arch/alpha/system.hh index a934550b7..da42ab263 100644 --- a/src/arch/alpha/system.hh +++ b/src/arch/alpha/system.hh @@ -49,10 +49,10 @@ class AlphaSystem : public System AlphaSystem(Params *p); ~AlphaSystem(); -/** - * Serialization stuff - */ public: + /** + * Serialization stuff + */ virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); @@ -77,26 +77,28 @@ class AlphaSystem : public System /** Event to halt the simulator if the console calls panic() */ BreakPCEvent *consolePanicEvent; #endif + protected: const Params *params() const { return (const Params *)_params; } /** Add a function-based event to PALcode. */ template - T *addPalFuncEvent(const char *lbl) + T * + addPalFuncEvent(const char *lbl) { return addFuncEvent(palSymtab, lbl); } /** Add a function-based event to the console code. */ template - T *addConsoleFuncEvent(const char *lbl) + T * + addConsoleFuncEvent(const char *lbl) { return addFuncEvent(consoleSymtab, lbl); } virtual Addr fixFuncEventAddr(Addr addr); - }; -#endif +#endif // __ARCH_ALPHA_SYSTEM_HH__ diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc index 5e231d4d8..9266b8337 100644 --- a/src/arch/alpha/tlb.cc +++ b/src/arch/alpha/tlb.cc @@ -45,16 +45,18 @@ using namespace std; namespace AlphaISA { + /////////////////////////////////////////////////////////////////////// // // Alpha TLB // + #ifdef DEBUG bool uncacheBit39 = false; bool uncacheBit40 = false; #endif -#define MODE2MASK(X) (1 << (X)) +#define MODE2MASK(X) (1 << (X)) TLB::TLB(const Params *p) : BaseTLB(p), size(p->size), nlu(0) @@ -113,20 +115,20 @@ TLB::lookup(Addr vpn, uint8_t asn) return retval; } - Fault TLB::checkCacheability(RequestPtr &req, bool itb) { -// in Alpha, cacheability is controlled by upper-level bits of the -// physical address - -/* - * We support having the uncacheable bit in either bit 39 or bit 40. - * The Turbolaser platform (and EV5) support having the bit in 39, but - * Tsunami (which Linux assumes uses an EV6) generates accesses with - * the bit in 40. So we must check for both, but we have debug flags - * to catch a weird case where both are used, which shouldn't happen. - */ + // in Alpha, cacheability is controlled by upper-level bits of the + // physical address + + /* + * We support having the uncacheable bit in either bit 39 or bit + * 40. The Turbolaser platform (and EV5) support having the bit + * in 39, but Tsunami (which Linux assumes uses an EV6) generates + * accesses with the bit in 40. So we must check for both, but we + * have debug flags to catch a weird case where both are used, + * which shouldn't happen. + */ #if ALPHA_TLASER @@ -143,7 +145,8 @@ TLB::checkCacheability(RequestPtr &req, bool itb) req->setFlags(req->getFlags() | UNCACHEABLE); #if !ALPHA_TLASER - // Clear bits 42:35 of the physical address (10-2 in Tsunami manual) + // Clear bits 42:35 of the physical address (10-2 in + // Tsunami manual) req->setPaddr(req->getPaddr() & PAddrUncachedMask); #endif } @@ -221,7 +224,8 @@ TLB::flushProcesses() ++i; if (!entry->asma) { - DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, entry->tag, entry->ppn); + DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, + entry->tag, entry->ppn); entry->valid = false; lookupTable.erase(cur); } @@ -284,7 +288,6 @@ TLB::unserialize(Checkpoint *cp, const string §ion) } } - /////////////////////////////////////////////////////////////////////// // // Alpha ITB @@ -313,12 +316,11 @@ ITB::regStats() accesses = hits + misses; } - Fault ITB::translate(RequestPtr &req, ThreadContext *tc) { //If this is a pal pc, then set PHYSICAL - if(FULL_SYSTEM && PcPAL(req->getPC())) + if (FULL_SYSTEM && PcPAL(req->getPC())) req->setFlags(req->getFlags() | PHYSICAL); if (PcPAL(req->getPC())) { @@ -403,7 +405,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) // // Alpha DTB // - DTB::DTB(const Params *p) +DTB::DTB(const Params *p) : TLB(p) {} @@ -484,7 +486,6 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) mode_type mode = (mode_type)DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM)); - /** * Check for alignment faults */ @@ -522,14 +523,15 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) #endif { - // only valid in kernel mode if (DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM)) != mode_kernel) { if (write) { write_acv++; } else { read_acv++; } uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK); - return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags); + + return new DtbAcvFault(req->getVaddr(), req->getFlags(), + flags); } req->setPaddr(req->getVaddr() & PAddrImplMask); @@ -575,25 +577,28 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) uint64_t flags = MM_STAT_WR_MASK | MM_STAT_ACV_MASK | (entry->fonw ? MM_STAT_FONW_MASK : 0); - return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); + return new DtbPageFault(req->getVaddr(), req->getFlags(), + flags); } if (entry->fonw) { write_acv++; - uint64_t flags = MM_STAT_WR_MASK | - MM_STAT_FONW_MASK; - return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); + uint64_t flags = MM_STAT_WR_MASK | MM_STAT_FONW_MASK; + return new DtbPageFault(req->getVaddr(), req->getFlags(), + flags); } } else { if (!(entry->xre & MODE2MASK(mode))) { read_acv++; uint64_t flags = MM_STAT_ACV_MASK | (entry->fonr ? MM_STAT_FONR_MASK : 0); - return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags); + return new DtbAcvFault(req->getVaddr(), req->getFlags(), + flags); } if (entry->fonr) { read_acv++; uint64_t flags = MM_STAT_FONR_MASK; - return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); + return new DtbPageFault(req->getVaddr(), req->getFlags(), + flags); } } } @@ -622,7 +627,7 @@ TLB::index(bool advance) return *entry; } -} // namespace AlphaISA +/* end namespace AlphaISA */ } AlphaISA::ITB * AlphaITBParams::create() diff --git a/src/arch/alpha/tlb.hh b/src/arch/alpha/tlb.hh index f127d09a7..9267aa573 100644 --- a/src/arch/alpha/tlb.hh +++ b/src/arch/alpha/tlb.hh @@ -29,8 +29,8 @@ * Steve Reinhardt */ -#ifndef __ALPHA_MEMORY_HH__ -#define __ALPHA_MEMORY_HH__ +#ifndef __ARCH_ALPHA_TLB_HH__ +#define __ARCH_ALPHA_TLB_HH__ #include @@ -48,110 +48,116 @@ class ThreadContext; -namespace AlphaISA +namespace AlphaISA { + +class TlbEntry; + +class TLB : public BaseTLB { - class TlbEntry; + protected: + typedef std::multimap PageTable; + PageTable lookupTable; // Quick lookup into page table + + TlbEntry *table; // the Page Table + int size; // TLB Size + int nlu; // not last used entry (for replacement) + + void nextnlu() { if (++nlu >= size) nlu = 0; } + TlbEntry *lookup(Addr vpn, uint8_t asn); + + public: + typedef AlphaTLBParams Params; + TLB(const Params *p); + virtual ~TLB(); + + int getsize() const { return size; } + + TlbEntry &index(bool advance = true); + void insert(Addr vaddr, TlbEntry &entry); - class TLB : public BaseTLB + void flushAll(); + void flushProcesses(); + void flushAddr(Addr addr, uint8_t asn); + + void + demapPage(Addr vaddr, uint64_t asn) { - protected: - typedef std::multimap PageTable; - PageTable lookupTable; // Quick lookup into page table - - TlbEntry *table; // the Page Table - int size; // TLB Size - int nlu; // not last used entry (for replacement) - - void nextnlu() { if (++nlu >= size) nlu = 0; } - TlbEntry *lookup(Addr vpn, uint8_t asn); - - public: - typedef AlphaTLBParams Params; - TLB(const Params *p); - virtual ~TLB(); - - int getsize() const { return size; } - - TlbEntry &index(bool advance = true); - void insert(Addr vaddr, TlbEntry &entry); - - void flushAll(); - void flushProcesses(); - void flushAddr(Addr addr, uint8_t asn); - - void demapPage(Addr vaddr, uint64_t asn) - { - assert(asn < (1 << 8)); - flushAddr(vaddr, asn); - } - - // static helper functions... really EV5 VM traits - static bool validVirtualAddress(Addr vaddr) { - // unimplemented bits must be all 0 or all 1 - Addr unimplBits = vaddr & VAddrUnImplMask; - return (unimplBits == 0) || (unimplBits == VAddrUnImplMask); - } - - static Fault checkCacheability(RequestPtr &req, bool itb = false); - - // Checkpointing - virtual void serialize(std::ostream &os); - virtual void unserialize(Checkpoint *cp, const std::string §ion); - - // Most recently used page table entries - TlbEntry *EntryCache[3]; - inline void flushCache() - { - memset(EntryCache, 0, 3 * sizeof(TlbEntry*)); - } - - inline TlbEntry* updateCache(TlbEntry *entry) { - EntryCache[2] = EntryCache[1]; - EntryCache[1] = EntryCache[0]; - EntryCache[0] = entry; - return entry; - } - }; - - class ITB : public TLB + assert(asn < (1 << 8)); + flushAddr(vaddr, asn); + } + + // static helper functions... really EV5 VM traits + static bool + validVirtualAddress(Addr vaddr) { - protected: - mutable Stats::Scalar<> hits; - mutable Stats::Scalar<> misses; - mutable Stats::Scalar<> acv; - mutable Stats::Formula accesses; + // unimplemented bits must be all 0 or all 1 + Addr unimplBits = vaddr & VAddrUnImplMask; + return unimplBits == 0 || unimplBits == VAddrUnImplMask; + } - public: - typedef AlphaITBParams Params; - ITB(const Params *p); - virtual void regStats(); + static Fault checkCacheability(RequestPtr &req, bool itb = false); - Fault translate(RequestPtr &req, ThreadContext *tc); - }; + // Checkpointing + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); - class DTB : public TLB + // Most recently used page table entries + TlbEntry *EntryCache[3]; + inline void + flushCache() { - protected: - mutable Stats::Scalar<> read_hits; - mutable Stats::Scalar<> read_misses; - mutable Stats::Scalar<> read_acv; - mutable Stats::Scalar<> read_accesses; - mutable Stats::Scalar<> write_hits; - mutable Stats::Scalar<> write_misses; - mutable Stats::Scalar<> write_acv; - mutable Stats::Scalar<> write_accesses; - Stats::Formula hits; - Stats::Formula misses; - Stats::Formula acv; - Stats::Formula accesses; - - public: - typedef AlphaDTBParams Params; - DTB(const Params *p); - virtual void regStats(); - - Fault translate(RequestPtr &req, ThreadContext *tc, bool write); - }; -} - -#endif // __ALPHA_MEMORY_HH__ + memset(EntryCache, 0, 3 * sizeof(TlbEntry*)); + } + + inline TlbEntry * + updateCache(TlbEntry *entry) { + EntryCache[2] = EntryCache[1]; + EntryCache[1] = EntryCache[0]; + EntryCache[0] = entry; + return entry; + } +}; + +class ITB : public TLB +{ + protected: + mutable Stats::Scalar<> hits; + mutable Stats::Scalar<> misses; + mutable Stats::Scalar<> acv; + mutable Stats::Formula accesses; + + public: + typedef AlphaITBParams Params; + ITB(const Params *p); + virtual void regStats(); + + Fault translate(RequestPtr &req, ThreadContext *tc); +}; + +class DTB : public TLB +{ + protected: + mutable Stats::Scalar<> read_hits; + mutable Stats::Scalar<> read_misses; + mutable Stats::Scalar<> read_acv; + mutable Stats::Scalar<> read_accesses; + mutable Stats::Scalar<> write_hits; + mutable Stats::Scalar<> write_misses; + mutable Stats::Scalar<> write_acv; + mutable Stats::Scalar<> write_accesses; + Stats::Formula hits; + Stats::Formula misses; + Stats::Formula acv; + Stats::Formula accesses; + + public: + typedef AlphaDTBParams Params; + DTB(const Params *p); + virtual void regStats(); + + Fault translate(RequestPtr &req, ThreadContext *tc, bool write); +}; + +} // namespace AlphaISA + +#endif // __ARCH_ALPHA_TLB_HH__ diff --git a/src/arch/alpha/tru64/process.cc b/src/arch/alpha/tru64/process.cc index 455a24584..645cc6cf9 100644 --- a/src/arch/alpha/tru64/process.cc +++ b/src/arch/alpha/tru64/process.cc @@ -32,10 +32,8 @@ #include "arch/alpha/tru64/tru64.hh" #include "arch/alpha/isa_traits.hh" #include "arch/alpha/tru64/process.hh" - #include "cpu/thread_context.hh" #include "kern/tru64/tru64.hh" - #include "sim/process.hh" #include "sim/syscall_emul.hh" @@ -85,7 +83,7 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, case AlphaTru64::GSI_PHYSMEM: { TypedBufferArg physmem(tc->getSyscallArg(1)); - *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB + *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB physmem.copyOut(tc->getMemPort()); return 1; } @@ -159,14 +157,12 @@ setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, return 0; } - /// Target table() handler. -static -SyscallReturn tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process, - ThreadContext *tc) +static SyscallReturn +tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process, + ThreadContext *tc) { using namespace std; - using namespace AlphaISA; int id = tc->getSyscallArg(0); // table ID int index = tc->getSyscallArg(1); // index into table @@ -472,15 +468,14 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { /* 266 */ SyscallDesc("sendfile", unimplementedFunc), }; - - SyscallDesc AlphaTru64Process::machSyscallDescs[] = { /* 0 */ SyscallDesc("kern_invalid", unimplementedFunc), /* 1 */ SyscallDesc("m5_mutex_lock", AlphaTru64::m5_mutex_lockFunc), /* 2 */ SyscallDesc("m5_mutex_trylock", AlphaTru64::m5_mutex_trylockFunc), /* 3 */ SyscallDesc("m5_mutex_unlock", AlphaTru64::m5_mutex_unlockFunc), /* 4 */ SyscallDesc("m5_cond_signal", AlphaTru64::m5_cond_signalFunc), - /* 5 */ SyscallDesc("m5_cond_broadcast", AlphaTru64::m5_cond_broadcastFunc), + /* 5 */ SyscallDesc("m5_cond_broadcast", + AlphaTru64::m5_cond_broadcastFunc), /* 6 */ SyscallDesc("m5_cond_wait", AlphaTru64::m5_cond_waitFunc), /* 7 */ SyscallDesc("m5_thread_exit", AlphaTru64::m5_thread_exitFunc), /* 8 */ SyscallDesc("kern_invalid", unimplementedFunc), @@ -507,7 +502,8 @@ SyscallDesc AlphaTru64Process::machSyscallDescs[] = { /* 29 */ SyscallDesc("nxm_thread_destroy", unimplementedFunc), /* 30 */ SyscallDesc("lw_wire", unimplementedFunc), /* 31 */ SyscallDesc("lw_unwire", unimplementedFunc), - /* 32 */ SyscallDesc("nxm_thread_create", AlphaTru64::nxm_thread_createFunc), + /* 32 */ SyscallDesc("nxm_thread_create", + AlphaTru64::nxm_thread_createFunc), /* 33 */ SyscallDesc("nxm_task_init", AlphaTru64::nxm_task_initFunc), /* 34 */ SyscallDesc("kern_invalid", unimplementedFunc), /* 35 */ SyscallDesc("nxm_idle", AlphaTru64::nxm_idleFunc), @@ -572,9 +568,8 @@ AlphaTru64Process::getDesc(int callnum) return &syscallDescs[callnum]; } - -AlphaTru64Process::AlphaTru64Process(LiveProcessParams * params, - ObjectFile *objFile) +AlphaTru64Process::AlphaTru64Process(LiveProcessParams *params, + ObjectFile *objFile) : AlphaLiveProcess(params, objFile), Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)), Num_Mach_Syscall_Descs(sizeof(machSyscallDescs) / sizeof(SyscallDesc)) diff --git a/src/arch/alpha/tru64/process.hh b/src/arch/alpha/tru64/process.hh index 16bc499c6..6d7a76555 100644 --- a/src/arch/alpha/tru64/process.hh +++ b/src/arch/alpha/tru64/process.hh @@ -28,12 +28,13 @@ * Authors: Steve Reinhardt */ -#ifndef __ALPHA_TRU64_PROCESS_HH__ -#define __ALPHA_TRU64_PROCESS_HH__ +#ifndef __ARCH_ALPHA_TRU64_PROCESS_HH__ +#define __ARCH_ALPHA_TRU64_PROCESS_HH__ #include "arch/alpha/process.hh" namespace AlphaISA { + /// A process with emulated Alpha Tru64 syscalls. class AlphaTru64Process : public AlphaLiveProcess { @@ -51,9 +52,9 @@ class AlphaTru64Process : public AlphaLiveProcess const int Num_Syscall_Descs; const int Num_Mach_Syscall_Descs; - virtual SyscallDesc* getDesc(int callnum); + virtual SyscallDesc *getDesc(int callnum); }; } // namespace AlphaISA -#endif // __ALPHA_TRU64_PROCESS_HH__ +#endif // __ARCH_ALPHA_TRU64_PROCESS_HH__ diff --git a/src/arch/alpha/tru64/tru64.hh b/src/arch/alpha/tru64/tru64.hh index 8aa959553..4ba35fc50 100644 --- a/src/arch/alpha/tru64/tru64.hh +++ b/src/arch/alpha/tru64/tru64.hh @@ -28,14 +28,13 @@ * Authors: Korey Sewell */ -#ifndef __ALPHA_ALPHA_TRU64_HH -#define __ALPHA_ALPHA_TRU64_HH +#ifndef __ALPHA_ALPHA_TRU64_TRU64_HH__ +#define __ALPHA_ALPHA_TRU64_TRU64_HH__ #include "kern/tru64/tru64.hh" class AlphaTru64 : public Tru64 { - public: /// This table maps the target open() flags to the corresponding /// host open() flags. @@ -68,13 +67,13 @@ class AlphaTru64 : public Tru64 //@{ /// For getsysinfo(). - static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string - static const unsigned GSI_CPU_INFO = 59; //!< CPU information - static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type - static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine - static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system - static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB - static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz + static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name string + static const unsigned GSI_CPU_INFO = 59; //!< CPU information + static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type + static const unsigned GSI_MAX_CPU = 30; //!< max # CPUs on machine + static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system + static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB + static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz //@} //@{ @@ -124,6 +123,4 @@ class AlphaTru64 : public Tru64 }; }; - - -#endif +#endif // __ALPHA_ALPHA_TRU64_TRU64_HH__ diff --git a/src/arch/alpha/types.hh b/src/arch/alpha/types.hh index f6648b776..94a4cb0e9 100644 --- a/src/arch/alpha/types.hh +++ b/src/arch/alpha/types.hh @@ -32,47 +32,50 @@ #ifndef __ARCH_ALPHA_TYPES_HH__ #define __ARCH_ALPHA_TYPES_HH__ -#include +#include "sim/host.hh" -namespace AlphaISA -{ +namespace AlphaISA { + +typedef uint32_t MachInst; +typedef uint64_t ExtMachInst; +typedef uint8_t RegIndex; - typedef uint32_t MachInst; - typedef uint64_t ExtMachInst; - typedef uint8_t RegIndex; +typedef uint64_t IntReg; +typedef uint64_t LargestRead; - typedef uint64_t IntReg; - typedef uint64_t LargestRead; +// floating point register file entry type +typedef double FloatReg; +typedef uint64_t FloatRegBits; - // floating point register file entry type - typedef double FloatReg; - typedef uint64_t FloatRegBits; +// control register file contents +typedef uint64_t MiscReg; - // control register file contents - typedef uint64_t MiscReg; +union AnyReg +{ + IntReg intreg; + FloatReg fpreg; + MiscReg ctrlreg; +}; - typedef union { - IntReg intreg; - FloatReg fpreg; - MiscReg ctrlreg; - } AnyReg; +enum RegContextParam +{ + CONTEXT_PALMODE +}; - enum RegContextParam - { - CONTEXT_PALMODE - }; +typedef bool RegContextVal; - typedef bool RegContextVal; +enum annotes +{ + ANNOTE_NONE = 0, + // An impossible number for instruction annotations + ITOUCH_ANNOTE = 0xffffffff, +}; - enum annotes { - ANNOTE_NONE = 0, - // An impossible number for instruction annotations - ITOUCH_ANNOTE = 0xffffffff, - }; +struct CoreSpecific +{ + int core_type; +}; - struct CoreSpecific { - int core_type; - }; } // namespace AlphaISA -#endif +#endif // __ARCH_ALPHA_TYPES_HH__ diff --git a/src/arch/alpha/utility.cc b/src/arch/alpha/utility.cc index 23abceb93..2cf64b799 100644 --- a/src/arch/alpha/utility.cc +++ b/src/arch/alpha/utility.cc @@ -36,10 +36,10 @@ #include "mem/vport.hh" #endif -namespace AlphaISA -{ +namespace AlphaISA { -uint64_t getArgument(ThreadContext *tc, int number, bool fp) +uint64_t +getArgument(ThreadContext *tc, int number, bool fp) { #if FULL_SYSTEM if (number < NumArgumentRegs) { @@ -56,7 +56,7 @@ uint64_t getArgument(ThreadContext *tc, int number, bool fp) } #else panic("getArgument() is Full system only\n"); - M5_DUMMY_RETURN + M5_DUMMY_RETURN; #endif } diff --git a/src/arch/alpha/utility.hh b/src/arch/alpha/utility.hh index 220aa6695..84f7cc487 100644 --- a/src/arch/alpha/utility.hh +++ b/src/arch/alpha/utility.hh @@ -32,137 +32,137 @@ #ifndef __ARCH_ALPHA_UTILITY_HH__ #define __ARCH_ALPHA_UTILITY_HH__ -#include "config/full_system.hh" #include "arch/alpha/types.hh" #include "arch/alpha/isa_traits.hh" #include "arch/alpha/regfile.hh" #include "base/misc.hh" +#include "config/full_system.hh" #include "cpu/thread_context.hh" -namespace AlphaISA +namespace AlphaISA { + +uint64_t getArgument(ThreadContext *tc, int number, bool fp); + +inline bool +inUserMode(ThreadContext *tc) +{ + return (tc->readMiscRegNoEffect(IPR_DTB_CM) & 0x18) != 0; +} + +inline bool +isCallerSaveIntegerRegister(unsigned int reg) +{ + panic("register classification not implemented"); + return (reg >= 1 && reg <= 8 || reg >= 22 && reg <= 25 || reg == 27); +} + +inline bool +isCalleeSaveIntegerRegister(unsigned int reg) +{ + panic("register classification not implemented"); + return (reg >= 9 && reg <= 15); +} + +inline bool +isCallerSaveFloatRegister(unsigned int reg) { - uint64_t getArgument(ThreadContext *tc, int number, bool fp); - - inline bool - inUserMode(ThreadContext *tc) - { - return (tc->readMiscRegNoEffect(IPR_DTB_CM) & 0x18) != 0; - } - - inline bool - isCallerSaveIntegerRegister(unsigned int reg) - { - panic("register classification not implemented"); - return (reg >= 1 && reg <= 8 || reg >= 22 && reg <= 25 || reg == 27); - } - - inline bool - isCalleeSaveIntegerRegister(unsigned int reg) - { - panic("register classification not implemented"); - return (reg >= 9 && reg <= 15); - } - - inline bool - isCallerSaveFloatRegister(unsigned int reg) - { - panic("register classification not implemented"); - return false; - } - - inline bool - isCalleeSaveFloatRegister(unsigned int reg) - { - panic("register classification not implemented"); - return false; - } - - inline Addr - alignAddress(const Addr &addr, unsigned int nbytes) - { - return (addr & ~(nbytes - 1)); - } - - // Instruction address compression hooks - inline Addr - realPCToFetchPC(const Addr &addr) - { - return addr; - } - - inline Addr - fetchPCToRealPC(const Addr &addr) - { - return addr; - } - - // the size of "fetched" instructions (not necessarily the size - // of real instructions for PISA) - inline size_t - fetchInstSize() - { - return sizeof(MachInst); - } - - inline MachInst - makeRegisterCopy(int dest, int src) - { - panic("makeRegisterCopy not implemented"); - return 0; - } - - // Machine operations - void saveMachineReg(AnyReg &savereg, const RegFile ®_file, int regnum); - void restoreMachineReg(RegFile ®s, const AnyReg ®, int regnum); - - /** - * Function to insure ISA semantics about 0 registers. - * @param tc The thread context. - */ - template - void zeroRegisters(TC *tc); - - // Alpha IPR register accessors - inline bool PcPAL(Addr addr) { return addr & 0x3; } - inline void startupCPU(ThreadContext *tc, int cpuId) { tc->activate(0); } - - //////////////////////////////////////////////////////////////////////// - // - // Translation stuff - // - - inline Addr PteAddr(Addr a) { return (a & PteMask) << PteShift; } - - // User Virtual - inline bool IsUSeg(Addr a) { return USegBase <= a && a <= USegEnd; } - - // Kernel Direct Mapped - inline bool IsK0Seg(Addr a) { return K0SegBase <= a && a <= K0SegEnd; } - inline Addr K0Seg2Phys(Addr addr) { return addr & ~K0SegBase; } - - // Kernel Virtual - inline bool IsK1Seg(Addr a) { return K1SegBase <= a && a <= K1SegEnd; } - - inline Addr - TruncPage(Addr addr) - { return addr & ~(PageBytes - 1); } - - inline Addr - RoundPage(Addr addr) - { return (addr + PageBytes - 1) & ~(PageBytes - 1); } - - void initIPRs(ThreadContext *tc, int cpuId); + panic("register classification not implemented"); + return false; +} + +inline bool +isCalleeSaveFloatRegister(unsigned int reg) +{ + panic("register classification not implemented"); + return false; +} + +inline Addr +alignAddress(const Addr &addr, unsigned int nbytes) +{ + return (addr & ~(nbytes - 1)); +} + +// Instruction address compression hooks +inline Addr +realPCToFetchPC(const Addr &addr) +{ + return addr; +} + +inline Addr +fetchPCToRealPC(const Addr &addr) +{ + return addr; +} + +// the size of "fetched" instructions (not necessarily the size +// of real instructions for PISA) +inline size_t +fetchInstSize() +{ + return sizeof(MachInst); +} + +inline MachInst +makeRegisterCopy(int dest, int src) +{ + panic("makeRegisterCopy not implemented"); + return 0; +} + +// Machine operations +void saveMachineReg(AnyReg &savereg, const RegFile ®_file, int regnum); +void restoreMachineReg(RegFile ®s, const AnyReg ®, int regnum); + +/** + * Function to insure ISA semantics about 0 registers. + * @param tc The thread context. + */ +template +void zeroRegisters(TC *tc); + +// Alpha IPR register accessors +inline bool PcPAL(Addr addr) { return addr & 0x3; } +inline void startupCPU(ThreadContext *tc, int cpuId) { tc->activate(0); } + +//////////////////////////////////////////////////////////////////////// +// +// Translation stuff +// + +inline Addr PteAddr(Addr a) { return (a & PteMask) << PteShift; } + +// User Virtual +inline bool IsUSeg(Addr a) { return USegBase <= a && a <= USegEnd; } + +// Kernel Direct Mapped +inline bool IsK0Seg(Addr a) { return K0SegBase <= a && a <= K0SegEnd; } +inline Addr K0Seg2Phys(Addr addr) { return addr & ~K0SegBase; } + +// Kernel Virtual +inline bool IsK1Seg(Addr a) { return K1SegBase <= a && a <= K1SegEnd; } + +inline Addr +TruncPage(Addr addr) +{ return addr & ~(PageBytes - 1); } + +inline Addr +RoundPage(Addr addr) +{ return (addr + PageBytes - 1) & ~(PageBytes - 1); } + +void initIPRs(ThreadContext *tc, int cpuId); #if FULL_SYSTEM - void initCPU(ThreadContext *tc, int cpuId); - - /** - * Function to check for and process any interrupts. - * @param tc The thread context. - */ - template - void processInterrupts(TC *tc); +void initCPU(ThreadContext *tc, int cpuId); + +/** + * Function to check for and process any interrupts. + * @param tc The thread context. + */ +template +void processInterrupts(TC *tc); #endif } // namespace AlphaISA -#endif +#endif // __ARCH_ALPHA_UTILITY_HH__ diff --git a/src/arch/alpha/vtophys.cc b/src/arch/alpha/vtophys.cc index 88e5a3090..4a043d8d1 100644 --- a/src/arch/alpha/vtophys.cc +++ b/src/arch/alpha/vtophys.cc @@ -115,4 +115,3 @@ vtophys(ThreadContext *tc, Addr addr) } } // namespace AlphaISA - diff --git a/src/arch/alpha/vtophys.hh b/src/arch/alpha/vtophys.hh index 9cce85d6c..b13afd090 100644 --- a/src/arch/alpha/vtophys.hh +++ b/src/arch/alpha/vtophys.hh @@ -41,12 +41,13 @@ class FunctionalPort; namespace AlphaISA { - PageTableEntry - kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, VAddr vaddr); +PageTableEntry kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, + VAddr vaddr); - Addr vtophys(Addr vaddr); - Addr vtophys(ThreadContext *tc, Addr vaddr); +Addr vtophys(Addr vaddr); +Addr vtophys(ThreadContext *tc, Addr vaddr); + +} // namespace AlphaISA -}; #endif // __ARCH_ALPHA_VTOPHYS_H__ -- cgit v1.2.3 From 80d9be86e616e819cc3c9a0bbc8a42a5beb41247 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 27 Sep 2008 21:03:49 -0700 Subject: gcc: Add extra parens to quell warnings. Even though we're not incorrect about operator precedence, let's add some parens in some particularly confusing places to placate GCC 4.3 so that we don't have to turn the warning off. Agreed that this is a bit of a pain for those users who get the order of operations correct, but it is likely to prevent bugs in certain cases. --- src/arch/alpha/ev5.hh | 4 ++-- src/arch/alpha/pagetable.hh | 4 ++-- src/arch/alpha/utility.hh | 4 ++-- src/arch/mips/dsp.cc | 4 ++-- src/arch/mips/isa/decoder.isa | 26 +++++++++++++------------- src/arch/mips/pagetable.hh | 4 ++-- src/arch/mips/utility.cc | 2 +- src/arch/sparc/faults.cc | 2 +- src/arch/sparc/isa/formats/mem/util.isa | 9 +++++---- src/arch/sparc/tlb.cc | 8 ++++---- src/arch/x86/emulenv.cc | 2 +- src/arch/x86/insts/microop.cc | 4 ++-- src/arch/x86/predecoder.cc | 8 ++++---- src/arch/x86/regfile.cc | 2 +- 14 files changed, 42 insertions(+), 41 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/ev5.hh b/src/arch/alpha/ev5.hh index 4c4f282f1..1915d822b 100644 --- a/src/arch/alpha/ev5.hh +++ b/src/arch/alpha/ev5.hh @@ -80,7 +80,7 @@ Phys2K0Seg(Addr addr) inline int DTB_ASN_ASN(uint64_t reg) { return reg >> 57 & AsnMask; } inline Addr DTB_PTE_PPN(uint64_t reg) -{ return reg >> 32 & (ULL(1) << PAddrImplBits - PageShift) - 1; } +{ return reg >> 32 & ((ULL(1) << (PAddrImplBits - PageShift)) - 1); } inline int DTB_PTE_XRE(uint64_t reg) { return reg >> 8 & 0xf; } inline int DTB_PTE_XWE(uint64_t reg) { return reg >> 12 & 0xf; } inline int DTB_PTE_FONR(uint64_t reg) { return reg >> 1 & 0x1; } @@ -90,7 +90,7 @@ inline int DTB_PTE_ASMA(uint64_t reg) { return reg >> 4 & 0x1; } inline int ITB_ASN_ASN(uint64_t reg) { return reg >> 4 & AsnMask; } inline Addr ITB_PTE_PPN(uint64_t reg) -{ return reg >> 32 & (ULL(1) << PAddrImplBits - PageShift) - 1; } +{ return reg >> 32 & ((ULL(1) << (PAddrImplBits - PageShift)) - 1); } inline int ITB_PTE_XRE(uint64_t reg) { return reg >> 8 & 0xf; } inline bool ITB_PTE_FONR(uint64_t reg) { return reg >> 1 & 0x1; } inline bool ITB_PTE_FONW(uint64_t reg) { return reg >> 2 & 0x1; } diff --git a/src/arch/alpha/pagetable.hh b/src/arch/alpha/pagetable.hh index 4f7beb19b..6cf11be56 100644 --- a/src/arch/alpha/pagetable.hh +++ b/src/arch/alpha/pagetable.hh @@ -57,9 +57,9 @@ struct VAddr Addr level3() const { return PteAddr(addr >> PageShift); } Addr level2() const - { return PteAddr(addr >> NPtePageShift + PageShift); } + { return PteAddr(addr >> (NPtePageShift + PageShift)); } Addr level1() const - { return PteAddr(addr >> 2 * NPtePageShift + PageShift); } + { return PteAddr(addr >> (2 * NPtePageShift + PageShift)); } }; struct PageTableEntry diff --git a/src/arch/alpha/utility.hh b/src/arch/alpha/utility.hh index 84f7cc487..76c6c5726 100644 --- a/src/arch/alpha/utility.hh +++ b/src/arch/alpha/utility.hh @@ -53,14 +53,14 @@ inline bool isCallerSaveIntegerRegister(unsigned int reg) { panic("register classification not implemented"); - return (reg >= 1 && reg <= 8 || reg >= 22 && reg <= 25 || reg == 27); + return (reg >= 1 && reg <= 8) || (reg >= 22 && reg <= 25) || reg == 27; } inline bool isCalleeSaveIntegerRegister(unsigned int reg) { panic("register classification not implemented"); - return (reg >= 9 && reg <= 15); + return reg >= 9 && reg <= 15; } inline bool diff --git a/src/arch/mips/dsp.cc b/src/arch/mips/dsp.cc index fc3ae65d6..6e4f7afea 100755 --- a/src/arch/mips/dsp.cc +++ b/src/arch/mips/dsp.cc @@ -923,10 +923,10 @@ MipsISA::dspPrecrqu(int32_t a, int32_t b, uint32_t *dspctl) for (int i = 0; i<2; i++) { r_values[i] = - dspSaturate((int64_t)b_values[i] >> SIMD_NBITS[SIMD_FMT_QB] - 1, + dspSaturate((int64_t)b_values[i] >> (SIMD_NBITS[SIMD_FMT_QB] - 1), SIMD_FMT_QB, UNSIGNED, &ouflag); r_values[i + 2] = - dspSaturate((int64_t)a_values[i] >> SIMD_NBITS[SIMD_FMT_QB] - 1, + dspSaturate((int64_t)a_values[i] >> (SIMD_NBITS[SIMD_FMT_QB] - 1), SIMD_FMT_QB, UNSIGNED, &ouflag); } diff --git a/src/arch/mips/isa/decoder.isa b/src/arch/mips/isa/decoder.isa index b1cd03ca1..0a12c4f6e 100644 --- a/src/arch/mips/isa/decoder.isa +++ b/src/arch/mips/isa/decoder.isa @@ -416,16 +416,16 @@ decode OPCODE_HI default Unknown::unknown() { Ctrl_Base_DepTag); break; case 25: - data = 0 | fcsr_val & 0xFE000000 >> 24 - | fcsr_val & 0x00800000 >> 23; + data = (fcsr_val & 0xFE000000 >> 24) + | (fcsr_val & 0x00800000 >> 23); break; case 26: - data = 0 | fcsr_val & 0x0003F07C; + data = fcsr_val & 0x0003F07C; break; case 28: - data = 0 | fcsr_val & 0x00000F80 - | fcsr_val & 0x01000000 >> 21 - | fcsr_val & 0x00000003; + data = (fcsr_val & 0x00000F80) + | (fcsr_val & 0x01000000 >> 21) + | (fcsr_val & 0x00000003); break; case 31: data = fcsr_val; @@ -1963,7 +1963,7 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: decode OP_LO { format IntOp { 0x0: append({{ Rt.uw = (Rt.uw << RD) | bits(Rs.uw,RD-1,0); }}); - 0x1: prepend({{ Rt.uw = (Rt.uw >> RD) | (bits(Rs.uw,RD-1,0) << 32-RD); }}); + 0x1: prepend({{ Rt.uw = (Rt.uw >> RD) | (bits(Rs.uw, RD - 1, 0) << (32 - RD)); }}); } } 0x2: decode OP_LO { @@ -2050,11 +2050,11 @@ decode OPCODE_HI default Unknown::unknown() { format LoadUnalignedMemory { 0x2: lwl({{ uint32_t mem_shift = 24 - (8 * byte_offset); Rt.uw = mem_word << mem_shift | - Rt.uw & mask(mem_shift); + (Rt.uw & mask(mem_shift)); }}); 0x6: lwr({{ uint32_t mem_shift = 8 * byte_offset; - Rt.uw = Rt.uw & (mask(mem_shift) << (32 - mem_shift)) | - mem_word >> mem_shift; + Rt.uw = (Rt.uw & (mask(mem_shift) << (32 - mem_shift))) | + (mem_word >> mem_shift); }}); } } @@ -2069,12 +2069,12 @@ decode OPCODE_HI default Unknown::unknown() { format StoreUnalignedMemory { 0x2: swl({{ uint32_t reg_shift = 24 - (8 * byte_offset); uint32_t mem_shift = 32 - reg_shift; - mem_word = mem_word & (mask(reg_shift) << mem_shift) | - Rt.uw >> reg_shift; + mem_word = (mem_word & (mask(reg_shift) << mem_shift)) | + (Rt.uw >> reg_shift); }}); 0x6: swr({{ uint32_t reg_shift = 8 * byte_offset; mem_word = Rt.uw << reg_shift | - mem_word & (mask(reg_shift)); + (mem_word & (mask(reg_shift))); }}); } format CP0Control { diff --git a/src/arch/mips/pagetable.hh b/src/arch/mips/pagetable.hh index 8c43a7b0c..bbed94194 100755 --- a/src/arch/mips/pagetable.hh +++ b/src/arch/mips/pagetable.hh @@ -59,9 +59,9 @@ namespace MipsISA { Addr level3() const { return MipsISA::PteAddr(addr >> PageShift); } Addr level2() const - { return MipsISA::PteAddr(addr >> NPtePageShift + PageShift); } + { return MipsISA::PteAddr(addr >> (NPtePageShift + PageShift)); } Addr level1() const - { return MipsISA::PteAddr(addr >> 2 * NPtePageShift + PageShift); } + { return MipsISA::PteAddr(addr >> (2 * NPtePageShift + PageShift)); } }; // ITB/DTB page table entry diff --git a/src/arch/mips/utility.cc b/src/arch/mips/utility.cc index 36cf76c67..1985c0f43 100644 --- a/src/arch/mips/utility.cc +++ b/src/arch/mips/utility.cc @@ -145,7 +145,7 @@ genCCVector(uint32_t fcsr, int cc_num, uint32_t cc_val) { int cc_idx = (cc_num == 0) ? 23 : cc_num + 24; - fcsr = bits(fcsr, 31, cc_idx + 1) << cc_idx + 1 | + fcsr = bits(fcsr, 31, cc_idx + 1) << (cc_idx + 1) | cc_val << cc_idx | bits(fcsr, cc_idx - 1, 0); diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index e201cef95..9c189d164 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -546,7 +546,7 @@ void SparcFaultBase::invoke(ThreadContext * tc) doNormalFault(tc, trapType(), true); getHyperVector(tc, PC, NPC, 2); } else if (level == Hyperprivileged || - level == Privileged && trapType() >= 384) { + (level == Privileged && trapType() >= 384)) { doNormalFault(tc, trapType(), true); getHyperVector(tc, PC, NPC, trapType()); } else { diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa index 38cde9a50..f2a2327ee 100644 --- a/src/arch/sparc/isa/formats/mem/util.isa +++ b/src/arch/sparc/isa/formats/mem/util.isa @@ -314,10 +314,11 @@ let {{ # are split into ones that are available in priv and hpriv, and # those that are only available in hpriv AlternateASIPrivFaultCheck = ''' - if(!bits(Pstate,2,2) && !bits(Hpstate,2,2) && !AsiIsUnPriv((ASI)EXT_ASI) || - !bits(Hpstate,2,2) && AsiIsHPriv((ASI)EXT_ASI)) - fault = new PrivilegedAction; - else if(AsiIsAsIfUser((ASI)EXT_ASI) && !bits(Pstate,2,2)) + if ((!bits(Pstate,2,2) && !bits(Hpstate,2,2) && + !AsiIsUnPriv((ASI)EXT_ASI)) || + (!bits(Hpstate,2,2) && AsiIsHPriv((ASI)EXT_ASI))) + fault = new PrivilegedAction; + else if (AsiIsAsIfUser((ASI)EXT_ASI) && !bits(Pstate,2,2)) fault = new PrivilegedAction; ''' diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index defa33c51..125ceba69 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -562,7 +562,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) asi = (ASI)req->getAsi(); bool implicit = false; bool hpriv = bits(tlbdata,0,0); - bool unaligned = (vaddr & size-1); + bool unaligned = vaddr & (size - 1); DPRINTF(TLB, "TLB: DTB Request to translate va=%#x size=%d asi=%#x\n", vaddr, size, asi); @@ -801,8 +801,8 @@ handleIntRegAccess: return new PrivilegedAction; } - if (asi == ASI_SWVR_UDB_INTR_W && !write || - asi == ASI_SWVR_UDB_INTR_R && write) { + if ((asi == ASI_SWVR_UDB_INTR_W && !write) || + (asi == ASI_SWVR_UDB_INTR_R && write)) { writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi); return new DataAccessException; } @@ -822,7 +822,7 @@ handleQueueRegAccess: writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi); return new PrivilegedAction; } - if (!hpriv && vaddr & 0xF || vaddr > 0x3f8 || vaddr < 0x3c0) { + if ((!hpriv && vaddr & 0xF) || vaddr > 0x3f8 || vaddr < 0x3c0) { writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi); return new DataAccessException; } diff --git a/src/arch/x86/emulenv.cc b/src/arch/x86/emulenv.cc index 31b705d79..142e233db 100644 --- a/src/arch/x86/emulenv.cc +++ b/src/arch/x86/emulenv.cc @@ -91,7 +91,7 @@ void EmulEnv::doModRM(const ExtMachInst & machInst) //Figure out what segment to use. This won't be entirely accurate since //the presence of a displacement is supposed to make the instruction //default to the data segment. - if (base != INTREG_RBP && base != INTREG_RSP || + if ((base != INTREG_RBP && base != INTREG_RSP) || 0/*Has an immediate offset*/) { seg = SEGMENT_REG_DS; //Handle any segment override that might have been in the instruction diff --git a/src/arch/x86/insts/microop.cc b/src/arch/x86/insts/microop.cc index 494c0b303..c7bfc3703 100644 --- a/src/arch/x86/insts/microop.cc +++ b/src/arch/x86/insts/microop.cc @@ -98,7 +98,7 @@ namespace X86ISA case ConditionTests::SxOF: return ccflags.sf ^ ccflags.of; case ConditionTests::SxOvZF: - return ccflags.sf ^ ccflags.of | ccflags.zf; + return (ccflags.sf ^ ccflags.of) | ccflags.zf; case ConditionTests::False: return false; case ConditionTests::NotECF: @@ -131,7 +131,7 @@ namespace X86ISA case ConditionTests::NotSxOF: return !(ccflags.sf ^ ccflags.of); case ConditionTests::NotSxOvZF: - return !(ccflags.sf ^ ccflags.of | ccflags.zf); + return !((ccflags.sf ^ ccflags.of) | ccflags.zf); } panic("Unknown condition: %d\n", condition); return true; diff --git a/src/arch/x86/predecoder.cc b/src/arch/x86/predecoder.cc index 1d415ffea..9d60089e3 100644 --- a/src/arch/x86/predecoder.cc +++ b/src/arch/x86/predecoder.cc @@ -319,17 +319,17 @@ namespace X86ISA if (emi.mode.submode != SixtyFourBitMode && !csAttr.defaultSize) { //figure out 16 bit displacement size - if(modRM.mod == 0 && modRM.rm == 6 || modRM.mod == 2) + if ((modRM.mod == 0 && modRM.rm == 6) || modRM.mod == 2) displacementSize = 2; - else if(modRM.mod == 1) + else if (modRM.mod == 1) displacementSize = 1; else displacementSize = 0; } else { //figure out 32/64 bit displacement size - if(modRM.mod == 0 && modRM.rm == 5 || modRM.mod == 2) + if ((modRM.mod == 0 && modRM.rm == 5) || modRM.mod == 2) displacementSize = 4; - else if(modRM.mod == 1) + else if (modRM.mod == 1) displacementSize = 1; else displacementSize = 0; diff --git a/src/arch/x86/regfile.cc b/src/arch/x86/regfile.cc index c27ab08ba..3fda345cc 100644 --- a/src/arch/x86/regfile.cc +++ b/src/arch/x86/regfile.cc @@ -214,7 +214,7 @@ int X86ISA::flattenIntIndex(ThreadContext * tc, int reg) //If we need to fold over the index to match byte semantics, do that. //Otherwise, just strip off any extra bits and pass it through. if (reg & (1 << 6)) - return (reg & ~(1 << 6) - 0x4); + return (reg & (~(1 << 6) - 0x4)); else return (reg & ~(1 << 6)); } -- cgit v1.2.3 From 1e9c428522144cb8df931e89314963ce8054a9d9 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 29 Sep 2008 07:15:30 -0700 Subject: alpha: Need to include cstring so that g++ 4.3 works. --- src/arch/alpha/floatregfile.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/arch') diff --git a/src/arch/alpha/floatregfile.cc b/src/arch/alpha/floatregfile.cc index 15dc13166..192b0f1d4 100644 --- a/src/arch/alpha/floatregfile.cc +++ b/src/arch/alpha/floatregfile.cc @@ -30,6 +30,8 @@ * Kevin Lim */ +#include + #include "arch/alpha/floatregfile.hh" #include "sim/serialize.hh" -- cgit v1.2.3 From 6c046a28dc6624f57655e5106568721972cbae1e Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Mon, 6 Oct 2008 02:07:04 -0400 Subject: fix shadow set bugs in MIPS code that caused out of bounds access... panic rdpgpr/wrpgpr instructions until a better impl. of MIPS shadow sets is available. --- src/arch/mips/isa/decoder.isa | 6 ++++-- src/arch/mips/isa_traits.hh | 2 ++ src/arch/mips/regfile/int_regfile.cc | 35 ++++++++++++++++++----------------- src/arch/mips/regfile/int_regfile.hh | 3 ++- src/arch/mips/regfile/misc_regfile.cc | 2 +- 5 files changed, 27 insertions(+), 21 deletions(-) (limited to 'src/arch') diff --git a/src/arch/mips/isa/decoder.isa b/src/arch/mips/isa/decoder.isa index 0a12c4f6e..8af504e55 100644 --- a/src/arch/mips/isa/decoder.isa +++ b/src/arch/mips/isa/decoder.isa @@ -603,7 +603,8 @@ decode OPCODE_HI default Unknown::unknown() { 0xA: rdpgpr({{ if(Config_AR >= 1) { // Rev 2 of the architecture - Rd = xc->tcBase()->readIntReg(RT + NumIntRegs * SRSCtl_PSS); + panic("Shadow Sets Not Fully Implemented.\n"); + //Rd = xc->tcBase()->readIntReg(RT + NumIntRegs * SRSCtl_PSS); } else { @@ -613,7 +614,8 @@ decode OPCODE_HI default Unknown::unknown() { 0xE: wrpgpr({{ if(Config_AR >= 1) { // Rev 2 of the architecture - xc->tcBase()->setIntReg(RD + NumIntRegs * SRSCtl_PSS,Rt); + panic("Shadow Sets Not Fully Implemented.\n"); + //xc->tcBase()->setIntReg(RD + NumIntRegs * SRSCtl_PSS,Rt); // warn("Writing %d to %d, PSS: %d, SRS: %x\n",Rt,RD + NumIntRegs * SRSCtl_PSS, SRSCtl_PSS,SRSCtl); } else diff --git a/src/arch/mips/isa_traits.hh b/src/arch/mips/isa_traits.hh index d4d1de479..3450c273e 100644 --- a/src/arch/mips/isa_traits.hh +++ b/src/arch/mips/isa_traits.hh @@ -181,6 +181,8 @@ namespace MipsISA const int NumIntRegs = NumIntArchRegs*NumShadowRegSets + NumIntSpecialRegs; //HI & LO Regs const int NumFloatRegs = NumFloatArchRegs + NumFloatSpecialRegs;// + const int TotalArchRegs = NumIntArchRegs * NumShadowRegSets; + // Static instruction parameters const int MaxInstSrcRegs = 10; const int MaxInstDestRegs = 8; diff --git a/src/arch/mips/regfile/int_regfile.cc b/src/arch/mips/regfile/int_regfile.cc index 4ffbcdfb8..88de4be94 100644 --- a/src/arch/mips/regfile/int_regfile.cc +++ b/src/arch/mips/regfile/int_regfile.cc @@ -44,6 +44,12 @@ IntRegFile::clear() currShadowSet=0; } +int +IntRegFile::readShadowSet() +{ + return currShadowSet; +} + void IntRegFile::setShadowSet(int css) { @@ -54,21 +60,17 @@ IntRegFile::setShadowSet(int css) IntReg IntRegFile::readReg(int intReg) { - if (intReg < NumIntRegs) { + if (intReg < NumIntArchRegs) { // Regular GPR Read DPRINTF(MipsPRA, "Reading Reg: %d, CurrShadowSet: %d\n", intReg, - currShadowSet); + currShadowSet); - if (intReg >= NumIntArchRegs * NumShadowRegSets) { - return regs[intReg + NumIntRegs * currShadowSet]; - } else { - int index = intReg + NumIntArchRegs * currShadowSet; - index = index % NumIntArchRegs; - return regs[index]; - } + return regs[intReg + NumIntArchRegs * currShadowSet]; } else { - // Read from shadow GPR .. probably called by RDPGPR - return regs[intReg]; + unsigned special_reg_num = intReg - NumIntArchRegs; + + // Read A Special Reg + return regs[TotalArchRegs + special_reg_num]; } } @@ -76,13 +78,12 @@ Fault IntRegFile::setReg(int intReg, const IntReg &val) { if (intReg != ZeroReg) { - if (intReg < NumIntRegs) { - if (intReg >= NumIntArchRegs * NumShadowRegSets) - regs[intReg] = val; - else - regs[intReg + NumIntRegs * currShadowSet] = val; + if (intReg < NumIntArchRegs) { + regs[intReg + NumIntArchRegs * currShadowSet] = val; } else { - regs[intReg] = val; + unsigned special_reg_num = intReg - NumIntArchRegs; + + regs[TotalArchRegs + special_reg_num] = val; } } diff --git a/src/arch/mips/regfile/int_regfile.hh b/src/arch/mips/regfile/int_regfile.hh index 8ddd276e6..0f453a382 100644 --- a/src/arch/mips/regfile/int_regfile.hh +++ b/src/arch/mips/regfile/int_regfile.hh @@ -48,7 +48,7 @@ namespace MipsISA } enum MiscIntRegNums { - LO = NumIntArchRegs*NumShadowRegSets, + LO = NumIntArchRegs, HI, DSPACX0, DSPLo1, @@ -72,6 +72,7 @@ namespace MipsISA int currShadowSet; public: void clear(); + int readShadowSet(); void setShadowSet(int css); IntReg readReg(int intReg); Fault setReg(int intReg, const IntReg &val); diff --git a/src/arch/mips/regfile/misc_regfile.cc b/src/arch/mips/regfile/misc_regfile.cc index e81f940f5..06523a8c9 100755 --- a/src/arch/mips/regfile/misc_regfile.cc +++ b/src/arch/mips/regfile/misc_regfile.cc @@ -40,7 +40,7 @@ #include "cpu/base.hh" #include "cpu/exetrace.hh" -#include "params/DerivO3CPU.hh" +//#include "params/DerivO3CPU.hh" using namespace std; -- cgit v1.2.3 From 569db520ad69bc8b3f506accb0a86d1e519e63ad Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 9 Oct 2008 00:04:36 -0700 Subject: X86: Make far ret modify CS instead of some random selector. --- src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py index b18d48264..d1a8245e6 100644 --- a/src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py +++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py @@ -109,8 +109,8 @@ processDescriptor: chks t2, t3, IretCheck, dataSize=8 # There should be validity checks on the RIP checks here, but I'll do # that later. - wrdl reg, t3, t2 - wrsel reg, t2 + wrdl cs, t3, t2 + wrsel cs, t2 wrip t0, t1 bri t0, label("end") -- cgit v1.2.3 From e1b306fa537bd8fba4c522ee313a2915f7daec61 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 9 Oct 2008 00:05:39 -0700 Subject: X86: Fix the debugging microops. The debug functions can't handle a string object format. --- src/arch/x86/isa/microops/debug.isa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/debug.isa b/src/arch/x86/isa/microops/debug.isa index 7456b0d4e..895e97199 100644 --- a/src/arch/x86/isa/microops/debug.isa +++ b/src/arch/x86/isa/microops/debug.isa @@ -104,7 +104,7 @@ def template MicroDebugExecute {{ %(op_decl)s %(op_rd)s if (%(cond_test)s) { - %(func)s(message + "\n"); + %(func)s("%s\n", message); } return NoFault; } -- cgit v1.2.3 From 523531a40e83b3023ae5911f48388e2490f16cba Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 9 Oct 2008 00:07:21 -0700 Subject: Microcode: Fix a very old bug with parsing external labels in microcode. --- src/arch/micro_asm.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/micro_asm.py b/src/arch/micro_asm.py index 36c9919c0..0982f6b89 100644 --- a/src/arch/micro_asm.py +++ b/src/arch/micro_asm.py @@ -242,7 +242,10 @@ def t_params_PARAMS(t): def t_asm_ID(t): r'[A-Za-z_]\w*' t.type = reserved_map.get(t.value, 'ID') - t.lexer.begin('params') + # If the ID is really "extern", we shouldn't start looking for parameters + # yet. The real ID, the label itself, is coming up. + if t.type != 'EXTERN': + t.lexer.begin('params') return t # If there is a label and you're -not- in the assembler (which would be caught -- cgit v1.2.3 From 975c9e3af869fb2905933c93c4d657e4d7187dad Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 9 Oct 2008 00:07:38 -0700 Subject: Microcode: Fix a silent typo error in the microcode assembler. --- src/arch/micro_asm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/micro_asm.py b/src/arch/micro_asm.py index 0982f6b89..3433a8076 100644 --- a/src/arch/micro_asm.py +++ b/src/arch/micro_asm.py @@ -141,7 +141,7 @@ def handle_statement(parser, container, statement): try: for label in statement.labels: container.labels[label.text] = microop - if label.extern: + if label.is_extern: container.externs[label.text] = microop container.add_microop(statement.mnemonic, microop) except: -- cgit v1.2.3 From f57c286d2c3fceae84fde60f148f70305c846772 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 9 Oct 2008 00:09:26 -0700 Subject: O3: Generaize the O3 dynamic instruction class so it isn't split out by ISA. --HG-- rename : src/cpu/o3/dyn_inst.hh => src/cpu/o3/dyn_inst_decl.hh rename : src/cpu/o3/alpha/dyn_inst_impl.hh => src/cpu/o3/dyn_inst_impl.hh --- src/arch/mips/locked_mem.hh | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'src/arch') diff --git a/src/arch/mips/locked_mem.hh b/src/arch/mips/locked_mem.hh index 34da79ed9..07dc9d588 100644 --- a/src/arch/mips/locked_mem.hh +++ b/src/arch/mips/locked_mem.hh @@ -49,11 +49,10 @@ template inline void handleLockedRead(XC *xc, Request *req) { - unsigned tid = req->getThreadNum(); - xc->setMiscRegNoEffect(LLAddr, req->getPaddr() & ~0xf, tid); - xc->setMiscRegNoEffect(LLFlag, true, tid); + xc->setMiscRegNoEffect(LLAddr, req->getPaddr() & ~0xf); + xc->setMiscRegNoEffect(LLFlag, true); DPRINTF(LLSC, "[tid:%i]: Load-Link Flag Set & Load-Link Address set to %x.\n", - tid, req->getPaddr() & ~0xf); + req->getThreadNum(), req->getPaddr() & ~0xf); } @@ -61,22 +60,20 @@ template inline bool handleLockedWrite(XC *xc, Request *req) { - unsigned tid = req->getThreadNum(); - if (req->isUncacheable()) { // Funky Turbolaser mailbox access...don't update // result register (see stq_c in decoder.isa) req->setExtraData(2); } else { // standard store conditional - bool lock_flag = xc->readMiscRegNoEffect(LLFlag, tid); - Addr lock_addr = xc->readMiscRegNoEffect(LLAddr, tid); + bool lock_flag = xc->readMiscRegNoEffect(LLFlag); + Addr lock_addr = xc->readMiscRegNoEffect(LLAddr); if (!lock_flag || (req->getPaddr() & ~0xf) != lock_addr) { // Lock flag not set or addr mismatch in CPU; // don't even bother sending to memory system req->setExtraData(0); - xc->setMiscRegNoEffect(LLFlag, false, tid); + xc->setMiscRegNoEffect(LLFlag, false); // the rest of this code is not architectural; // it's just a debugging aid to help detect @@ -97,10 +94,10 @@ handleLockedWrite(XC *xc, Request *req) if (!lock_flag){ DPRINTF(LLSC, "[tid:%i]: Lock Flag Set, Store Conditional Failed.\n", - tid); + req->getThreadNum()); } else if ((req->getPaddr() & ~0xf) != lock_addr) { DPRINTF(LLSC, "[tid:%i]: Load-Link Address Mismatch, Store Conditional Failed.\n", - tid); + req->getThreadNum()); } // store conditional failed already, so don't issue it to mem return false; -- cgit v1.2.3 From e06321091d4e931ff1a4d753e56d76f9746c3cd2 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 9 Oct 2008 04:58:24 -0700 Subject: eventq: convert all usage of events to use the new API. For now, there is still a single global event queue, but this is necessary for making the steps towards a parallelized m5. --- src/arch/alpha/regfile.cc | 6 ++++-- src/arch/alpha/regfile.hh | 6 ++++-- src/arch/mips/regfile/misc_regfile.cc | 10 +++------- src/arch/mips/regfile/regfile.cc | 5 +++-- src/arch/mips/regfile/regfile.hh | 8 +++++--- src/arch/sparc/miscregfile.cc | 13 ++++++++----- src/arch/sparc/miscregfile.hh | 5 +++-- src/arch/sparc/regfile.cc | 10 ++++++---- src/arch/sparc/regfile.hh | 5 +++-- src/arch/sparc/ua2005.cc | 30 +++++++++++++++++------------- src/arch/x86/miscregfile.hh | 6 ++---- src/arch/x86/regfile.cc | 6 ++++-- src/arch/x86/regfile.hh | 6 ++++-- 13 files changed, 66 insertions(+), 50 deletions(-) mode change 100755 => 100644 src/arch/mips/regfile/misc_regfile.cc (limited to 'src/arch') diff --git a/src/arch/alpha/regfile.cc b/src/arch/alpha/regfile.cc index cd648844f..b3aa55b19 100644 --- a/src/arch/alpha/regfile.cc +++ b/src/arch/alpha/regfile.cc @@ -33,10 +33,12 @@ #include "arch/alpha/regfile.hh" #include "cpu/thread_context.hh" +using namespace std; + namespace AlphaISA { void -RegFile::serialize(std::ostream &os) +RegFile::serialize(EventManager *em, ostream &os) { intRegFile.serialize(os); floatRegFile.serialize(os); @@ -49,7 +51,7 @@ RegFile::serialize(std::ostream &os) } void -RegFile::unserialize(Checkpoint *cp, const std::string §ion) +RegFile::unserialize(EventManager *em, Checkpoint *cp, const string §ion) { intRegFile.unserialize(cp, section); floatRegFile.unserialize(cp, section); diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh index c9fa8a91b..d6d2f587e 100644 --- a/src/arch/alpha/regfile.hh +++ b/src/arch/alpha/regfile.hh @@ -43,6 +43,7 @@ //XXX These should be implemented by someone who knows the alpha stuff better class Checkpoint; +class EventManager; class ThreadContext; namespace AlphaISA { @@ -202,8 +203,9 @@ class RegFile { intRegFile.setReg(intReg, val); } - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); + void serialize(EventManager *em, std::ostream &os); + void unserialize(EventManager *em, Checkpoint *cp, + const std::string §ion); void changeContext(RegContextParam param, RegContextVal val) diff --git a/src/arch/mips/regfile/misc_regfile.cc b/src/arch/mips/regfile/misc_regfile.cc old mode 100755 new mode 100644 index 06523a8c9..08487db90 --- a/src/arch/mips/regfile/misc_regfile.cc +++ b/src/arch/mips/regfile/misc_regfile.cc @@ -567,7 +567,7 @@ MiscRegFile::scheduleCP0Update(int delay) //schedule UPDATE CP0Event *cp0_event = new CP0Event(this, cpu, UpdateCP0); - cp0_event->schedule(curTick + cpu->ticks(delay)); + cpu->schedule(cp0_event, curTick + cpu->ticks(delay)); } } @@ -601,8 +601,7 @@ MiscRegFile::updateCPU() } MiscRegFile::CP0Event::CP0Event(CP0 *_cp0, BaseCPU *_cpu, CP0EventType e_type) - : Event(&mainEventQueue, CPU_Tick_Pri), cp0(_cp0), cpu(_cpu), - cp0EventType(e_type) + : Event(CPU_Tick_Pri), cp0(_cp0), cpu(_cpu), cp0EventType(e_type) { } void @@ -627,10 +626,7 @@ MiscRegFile::CP0Event::description() const void MiscRegFile::CP0Event::scheduleEvent(int delay) { - if (squashed()) - reschedule(curTick + cpu->ticks(delay)); - else if (!scheduled()) - schedule(curTick + cpu->ticks(delay)); + cpu->reschedule(this, curTick + cpu->ticks(delay), true); } void diff --git a/src/arch/mips/regfile/regfile.cc b/src/arch/mips/regfile/regfile.cc index 996c14f14..a1c8eab6a 100644 --- a/src/arch/mips/regfile/regfile.cc +++ b/src/arch/mips/regfile/regfile.cc @@ -193,7 +193,7 @@ RegFile::setNextNPC(Addr val) } void -RegFile::serialize(std::ostream &os) +RegFile::serialize(EventManager *em, std::ostream &os) { intRegFile.serialize(os); //SERIALIZE_ARRAY(floatRegFile, NumFloatRegs); @@ -207,7 +207,8 @@ RegFile::serialize(std::ostream &os) } void -RegFile::unserialize(Checkpoint *cp, const std::string §ion) +RegFile::unserialize(EventManager *em, Checkpoint *cp, + const std::string §ion) { intRegFile.unserialize(cp, section); //UNSERIALIZE_ARRAY(floatRegFile); diff --git a/src/arch/mips/regfile/regfile.hh b/src/arch/mips/regfile/regfile.hh index 407d9b50a..076cf45f5 100644 --- a/src/arch/mips/regfile/regfile.hh +++ b/src/arch/mips/regfile/regfile.hh @@ -41,8 +41,9 @@ //#include "cpu/base.hh" #include "sim/faults.hh" -class Checkpoint; class BaseCPU; +class Checkpoint; +class EventManager; namespace MipsISA { @@ -99,8 +100,9 @@ namespace MipsISA Addr readNextNPC(); void setNextNPC(Addr val); - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); + void serialize(EventManager *em, std::ostream &os); + void unserialize(EventManager *em, Checkpoint *cp, + const std::string §ion); void changeContext(RegContextParam param, RegContextVal val) { diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index 195db90a6..d66cefa7a 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -593,7 +593,8 @@ void MiscRegFile::setReg(int miscReg, setRegNoEffect(miscReg, new_val); } -void MiscRegFile::serialize(std::ostream & os) +void +MiscRegFile::serialize(EventManager *em, std::ostream &os) { SERIALIZE_SCALAR(asi); SERIALIZE_SCALAR(tick); @@ -670,7 +671,9 @@ void MiscRegFile::serialize(std::ostream & os) #endif } -void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section) +void +MiscRegFile::unserialize(EventManager *em, Checkpoint *cp, + const string §ion) { UNSERIALIZE_SCALAR(asi); UNSERIALIZE_SCALAR(tick); @@ -729,15 +732,15 @@ void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section) if (tick_cmp) { tickCompare = new TickCompareEvent(this, tc); - tickCompare->schedule(tick_cmp); + em->schedule(tickCompare, tick_cmp); } if (stick_cmp) { sTickCompare = new STickCompareEvent(this, tc); - sTickCompare->schedule(stick_cmp); + em->schedule(sTickCompare, stick_cmp); } if (hstick_cmp) { hSTickCompare = new HSTickCompareEvent(this, tc); - hSTickCompare->schedule(hstick_cmp); + em->schedule(hSTickCompare, hstick_cmp); } } } diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh index bf9c880fa..6a010f529 100644 --- a/src/arch/sparc/miscregfile.hh +++ b/src/arch/sparc/miscregfile.hh @@ -288,9 +288,10 @@ namespace SparcISA return priContext | (uint32_t)partId << 13; } - void serialize(std::ostream & os); + void serialize(EventManager *em, std::ostream & os); - void unserialize(Checkpoint * cp, const std::string & section); + void unserialize(EventManager *em, Checkpoint *cp, + const std::string & section); void copyMiscRegs(ThreadContext * tc); diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc index 76516daca..8815b094c 100644 --- a/src/arch/sparc/regfile.cc +++ b/src/arch/sparc/regfile.cc @@ -219,21 +219,23 @@ int SparcISA::flattenIntIndex(ThreadContext * tc, int reg) //return intRegFile.flattenIndex(reg); } -void RegFile::serialize(std::ostream &os) +void +RegFile::serialize(EventManager *em, ostream &os) { intRegFile.serialize(os); floatRegFile.serialize(os); - miscRegFile.serialize(os); + miscRegFile.serialize(em, os); SERIALIZE_SCALAR(pc); SERIALIZE_SCALAR(npc); SERIALIZE_SCALAR(nnpc); } -void RegFile::unserialize(Checkpoint *cp, const std::string §ion) +void +RegFile::unserialize(EventManager *em, Checkpoint *cp, const string §ion) { intRegFile.unserialize(cp, section); floatRegFile.unserialize(cp, section); - miscRegFile.unserialize(cp, section); + miscRegFile.unserialize(em, cp, section); UNSERIALIZE_SCALAR(pc); UNSERIALIZE_SCALAR(npc); UNSERIALIZE_SCALAR(nnpc); diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh index 581785714..da7e022e9 100644 --- a/src/arch/sparc/regfile.hh +++ b/src/arch/sparc/regfile.hh @@ -112,8 +112,9 @@ namespace SparcISA void setIntReg(int intReg, const IntReg &val); - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); + void serialize(EventManager *em, std::ostream &os); + void unserialize(EventManager *em, Checkpoint *cp, + const std::string §ion); public: diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index 990250159..7b8524703 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -84,12 +84,12 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) tickCompare = new TickCompareEvent(this, tc); setRegNoEffect(miscReg, val); if ((tick_cmpr & ~mask(63)) && tickCompare->scheduled()) - tickCompare->deschedule(); + cpu->deschedule(tickCompare); time = (tick_cmpr & mask(63)) - (tick & mask(63)); if (!(tick_cmpr & ~mask(63)) && time > 0) { if (tickCompare->scheduled()) - tickCompare->deschedule(); - tickCompare->schedule(time * cpu->ticks(1)); + cpu->deschedule(tickCompare); + cpu->schedule(tickCompare, curTick + time * cpu->ticks(1)); } panic("writing to TICK compare register %#X\n", val); break; @@ -99,13 +99,13 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) sTickCompare = new STickCompareEvent(this, tc); setRegNoEffect(miscReg, val); if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled()) - sTickCompare->deschedule(); + cpu->deschedule(sTickCompare); time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - cpu->instCount(); if (!(stick_cmpr & ~mask(63)) && time > 0) { if (sTickCompare->scheduled()) - sTickCompare->deschedule(); - sTickCompare->schedule(time * cpu->ticks(1) + curTick); + cpu->deschedule(sTickCompare); + cpu->schedule(sTickCompare, curTick + time * cpu->ticks(1)); } DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val); break; @@ -169,13 +169,13 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) hSTickCompare = new HSTickCompareEvent(this, tc); setRegNoEffect(miscReg, val); if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled()) - hSTickCompare->deschedule(); + cpu->deschedule(hSTickCompare); time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - cpu->instCount(); if (!(hstick_cmpr & ~mask(63)) && time > 0) { if (hSTickCompare->scheduled()) - hSTickCompare->deschedule(); - hSTickCompare->schedule(curTick + time * cpu->ticks(1)); + cpu->deschedule(hSTickCompare); + cpu->schedule(hSTickCompare, curTick + time * cpu->ticks(1)); } DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val); break; @@ -296,12 +296,14 @@ MiscRegFile::processTickCompare(ThreadContext *tc) void MiscRegFile::processSTickCompare(ThreadContext *tc) { + BaseCPU *cpu = tc->getCpuPtr(); + // since our microcode instructions take two cycles we need to check if // we're actually at the correct cycle or we need to wait a little while // more int ticks; ticks = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - - tc->getCpuPtr()->instCount(); + cpu->instCount(); assert(ticks >= 0 && "stick compare missed interrupt cycle"); if (ticks == 0 || tc->status() == ThreadContext::Suspended) { @@ -311,12 +313,14 @@ MiscRegFile::processSTickCompare(ThreadContext *tc) setReg(MISCREG_SOFTINT, softint | (ULL(1) << 16), tc); } } else - sTickCompare->schedule(ticks * tc->getCpuPtr()->ticks(1) + curTick); + cpu->schedule(sTickCompare, curTick + ticks * cpu->ticks(1)); } void MiscRegFile::processHSTickCompare(ThreadContext *tc) { + BaseCPU *cpu = tc->getCpuPtr(); + // since our microcode instructions take two cycles we need to check if // we're actually at the correct cycle or we need to wait a little while // more @@ -326,7 +330,7 @@ MiscRegFile::processHSTickCompare(ThreadContext *tc) return; ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - - tc->getCpuPtr()->instCount(); + cpu->instCount(); assert(ticks >= 0 && "hstick compare missed interrupt cycle"); if (ticks == 0 || tc->status() == ThreadContext::Suspended) { @@ -337,6 +341,6 @@ MiscRegFile::processHSTickCompare(ThreadContext *tc) } // Need to do something to cause interrupt to happen here !!! @todo } else - hSTickCompare->schedule(ticks * tc->getCpuPtr()->ticks(1) + curTick); + cpu->schedule(hSTickCompare, curTick + ticks * cpu->ticks(1)); } diff --git a/src/arch/x86/miscregfile.hh b/src/arch/x86/miscregfile.hh index 3abe4ec58..21caf3aa1 100644 --- a/src/arch/x86/miscregfile.hh +++ b/src/arch/x86/miscregfile.hh @@ -115,10 +115,8 @@ namespace X86ISA class ApicTimerEvent : public Event { public: - ApicTimerEvent() : Event(&mainEventQueue) - {} - - void process() + void + process() { warn("Local APIC timer event doesn't do anything!\n"); } diff --git a/src/arch/x86/regfile.cc b/src/arch/x86/regfile.cc index 3fda345cc..c8ec2a957 100644 --- a/src/arch/x86/regfile.cc +++ b/src/arch/x86/regfile.cc @@ -228,7 +228,8 @@ int X86ISA::flattenFloatIndex(ThreadContext * tc, int reg) return reg; } -void RegFile::serialize(std::ostream &os) +void +RegFile::serialize(EventManager *em, std::ostream &os) { intRegFile.serialize(os); floatRegFile.serialize(os); @@ -237,7 +238,8 @@ void RegFile::serialize(std::ostream &os) SERIALIZE_SCALAR(nextRip); } -void RegFile::unserialize(Checkpoint *cp, const std::string §ion) +void +RegFile::unserialize(EventManager *em, Checkpoint *cp, const string §ion) { intRegFile.unserialize(cp, section); floatRegFile.unserialize(cp, section); diff --git a/src/arch/x86/regfile.hh b/src/arch/x86/regfile.hh index 650181aca..3c2387346 100644 --- a/src/arch/x86/regfile.hh +++ b/src/arch/x86/regfile.hh @@ -68,6 +68,7 @@ #include class Checkpoint; +class EventManager; namespace X86ISA { @@ -139,8 +140,9 @@ namespace X86ISA void setIntReg(int intReg, const IntReg &val); - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); + void serialize(EventManager *em, std::ostream &os); + void unserialize(EventManager *em, Checkpoint *cp, + const std::string §ion); public: -- cgit v1.2.3 From 94b08bed07d13106381a0bb692bf0d879c5353d4 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 9 Oct 2008 22:19:39 -0700 Subject: SimObjects: Clean up handling of C++ namespaces. Make them easier to express by only having the cxx_type parameter which has the full namespace name, and drop the cxx_namespace thing. Add support for multiple levels of namespace. --- src/arch/alpha/AlphaTLB.py | 8 ++------ src/arch/mips/MipsTLB.py | 9 +++------ src/arch/sparc/SparcTLB.py | 8 ++------ src/arch/x86/X86TLB.py | 11 +++-------- src/arch/x86/bios/E820.py | 6 ++---- 5 files changed, 12 insertions(+), 30 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/AlphaTLB.py b/src/arch/alpha/AlphaTLB.py index fec245b75..7cfb549f3 100644 --- a/src/arch/alpha/AlphaTLB.py +++ b/src/arch/alpha/AlphaTLB.py @@ -35,14 +35,10 @@ class AlphaTLB(SimObject): class AlphaDTB(AlphaTLB): type = 'AlphaDTB' - cxx_namespace = 'AlphaISA' - cxx_class = 'DTB' - + cxx_class = 'AlphaISA::DTB' size = 64 class AlphaITB(AlphaTLB): type = 'AlphaITB' - cxx_namespace = 'AlphaISA' - cxx_class = 'ITB' - + cxx_class = 'AlphaISA::ITB' size = 48 diff --git a/src/arch/mips/MipsTLB.py b/src/arch/mips/MipsTLB.py index 1d0244e22..0054acae5 100644 --- a/src/arch/mips/MipsTLB.py +++ b/src/arch/mips/MipsTLB.py @@ -39,19 +39,16 @@ class MipsTLB(SimObject): class MipsDTB(MipsTLB): type = 'MipsDTB' - cxx_namespace = 'MipsISA' - cxx_class = 'DTB' + cxx_class = 'MipsISA::DTB' size = 64 class MipsITB(MipsTLB): type = 'MipsITB' - cxx_namespace = 'MipsISA' - cxx_class = 'ITB' + cxx_class = 'MipsISA::ITB' size = 64 class MipsUTB(MipsTLB): type = 'MipsUTB' - cxx_namespace = 'MipsISA' - cxx_class = 'UTB' + cxx_class = 'MipsISA::UTB' size = 64 diff --git a/src/arch/sparc/SparcTLB.py b/src/arch/sparc/SparcTLB.py index 2d0257cd7..20672a24e 100644 --- a/src/arch/sparc/SparcTLB.py +++ b/src/arch/sparc/SparcTLB.py @@ -35,14 +35,10 @@ class SparcTLB(SimObject): class SparcDTB(SparcTLB): type = 'SparcDTB' - cxx_namespace = 'SparcISA' - cxx_class = 'DTB' - + cxx_class = 'SparcISA::DTB' size = 64 class SparcITB(SparcTLB): type = 'SparcITB' - cxx_namespace = 'SparcISA' - cxx_class = 'ITB' - + cxx_class = 'SparcISA::ITB' size = 64 diff --git a/src/arch/x86/X86TLB.py b/src/arch/x86/X86TLB.py index 8dd53620e..c20566efb 100644 --- a/src/arch/x86/X86TLB.py +++ b/src/arch/x86/X86TLB.py @@ -62,8 +62,7 @@ from m5 import build_env if build_env['FULL_SYSTEM']: class X86PagetableWalker(MemObject): type = 'X86PagetableWalker' - cxx_namespace = 'X86ISA' - cxx_class = 'Walker' + cxx_class = 'X86ISA::Walker' port = Port("Port for the hardware table walker") system = Param.System(Parent.any, "system object") @@ -77,14 +76,10 @@ class X86TLB(SimObject): class X86DTB(X86TLB): type = 'X86DTB' - cxx_namespace = 'X86ISA' - cxx_class = 'DTB' - + cxx_class = 'X86ISA::DTB' size = 64 class X86ITB(X86TLB): type = 'X86ITB' - cxx_namespace = 'X86ISA' - cxx_class = 'ITB' - + cxx_class = 'X86ISA::ITB' size = 64 diff --git a/src/arch/x86/bios/E820.py b/src/arch/x86/bios/E820.py index e161cd56f..288c253fb 100644 --- a/src/arch/x86/bios/E820.py +++ b/src/arch/x86/bios/E820.py @@ -58,8 +58,7 @@ from m5.SimObject import SimObject class X86E820Entry(SimObject): type = 'X86E820Entry' - cxx_namespace = 'X86ISA' - cxx_class = 'E820Entry' + cxx_class = 'X86ISA::E820Entry' addr = Param.Addr(0, 'address of the beginning of the region') size = Param.MemorySize('0B', 'size of the region') @@ -67,7 +66,6 @@ class X86E820Entry(SimObject): class X86E820Table(SimObject): type = 'X86E820Table' - cxx_namespace = 'X86ISA' - cxx_class = 'E820Table' + cxx_class = 'X86ISA::E820Table' entries = VectorParam.X86E820Entry([], 'entries for the e820 table') -- cgit v1.2.3 From d897aa939f4fe558a8e41ba612d0f43931450677 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 10 Oct 2008 03:50:18 -0700 Subject: X86: Move the smbios objects into a folder for BIOS objects. --- src/arch/x86/SConscript | 3 - src/arch/x86/bios/SConscript | 65 ++++++++++ src/arch/x86/bios/smbios.cc | 245 ++++++++++++++++++++++++++++++++++++ src/arch/x86/bios/smbios.hh | 292 +++++++++++++++++++++++++++++++++++++++++++ src/arch/x86/smbios.cc | 245 ------------------------------------ src/arch/x86/smbios.hh | 292 ------------------------------------------- src/arch/x86/system.cc | 2 +- 7 files changed, 603 insertions(+), 541 deletions(-) create mode 100644 src/arch/x86/bios/SConscript create mode 100644 src/arch/x86/bios/smbios.cc create mode 100644 src/arch/x86/bios/smbios.hh delete mode 100644 src/arch/x86/smbios.cc delete mode 100644 src/arch/x86/smbios.hh (limited to 'src/arch') diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript index 184bb4809..0d8760fdc 100644 --- a/src/arch/x86/SConscript +++ b/src/arch/x86/SConscript @@ -110,13 +110,10 @@ if env['TARGET_ISA'] == 'x86': if env['FULL_SYSTEM']: SimObject('X86System.py') - SimObject('bios/E820.py') # Full-system sources - Source('bios/e820.cc') Source('linux/system.cc') Source('pagetable_walker.cc') - Source('smbios.cc') Source('system.cc') Source('stacktrace.cc') Source('vtophys.cc') diff --git a/src/arch/x86/bios/SConscript b/src/arch/x86/bios/SConscript new file mode 100644 index 000000000..904fab086 --- /dev/null +++ b/src/arch/x86/bios/SConscript @@ -0,0 +1,65 @@ +# -*- mode:python -*- + +# Copyright (c) 2007-2008 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use of this software in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# +# The software must be used only for Non-Commercial Use which means any +# use which is NOT directed to receiving any direct monetary +# compensation for, or commercial advantage from such use. Illustrative +# examples of non-commercial use are academic research, personal study, +# teaching, education and corporate research & development. +# Illustrative examples of commercial use are distributing products for +# commercial advantage and providing services using the software for +# commercial advantage. +# +# If you wish to use this software or functionality therein that may be +# covered by patents for commercial use, please contact: +# Director of Intellectual Property Licensing +# Office of Strategy and Technology +# Hewlett-Packard Company +# 1501 Page Mill Road +# Palo Alto, California 94304 +# +# Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. Redistributions +# in binary form must reproduce the above copyright notice, this list of +# conditions and the following disclaimer in the documentation and/or +# other materials provided with the distribution. Neither the name of +# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. No right of +# sublicense is granted herewith. Derivatives of the software and +# output created using the software may be prepared, but only for +# Non-Commercial Uses. Derivatives of the software may be shared with +# others provided: (i) the others agree to abide by the list of +# conditions herein which includes the Non-Commercial Use restrictions; +# and (ii) such Derivatives of the software include the above copyright +# notice to acknowledge the contribution from this software where +# applicable, this list of conditions and the disclaimer below. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Gabe Black + +Import('*') + +if env['TARGET_ISA'] == 'x86': + if env['FULL_SYSTEM']: + SimObject('E820.py') + Source('e820.cc') + + Source('smbios.cc') diff --git a/src/arch/x86/bios/smbios.cc b/src/arch/x86/bios/smbios.cc new file mode 100644 index 000000000..de4a263b7 --- /dev/null +++ b/src/arch/x86/bios/smbios.cc @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2008 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +/* + * Copyright (c) 2008 The Hewlett-Packard Development Company + * All rights reserved. + * + * Redistribution and use of this software in source and binary forms, + * with or without modification, are permitted provided that the + * following conditions are met: + * + * The software must be used only for Non-Commercial Use which means any + * use which is NOT directed to receiving any direct monetary + * compensation for, or commercial advantage from such use. Illustrative + * examples of non-commercial use are academic research, personal study, + * teaching, education and corporate research & development. + * Illustrative examples of commercial use are distributing products for + * commercial advantage and providing services using the software for + * commercial advantage. + * + * If you wish to use this software or functionality therein that may be + * covered by patents for commercial use, please contact: + * Director of Intellectual Property Licensing + * Office of Strategy and Technology + * Hewlett-Packard Company + * 1501 Page Mill Road + * Palo Alto, California 94304 + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. Redistributions + * in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. Neither the name of + * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. No right of + * sublicense is granted herewith. Derivatives of the software and + * output created using the software may be prepared, but only for + * Non-Commercial Uses. Derivatives of the software may be shared with + * others provided: (i) the others agree to abide by the list of + * conditions herein which includes the Non-Commercial Use restrictions; + * and (ii) such Derivatives of the software include the above copyright + * notice to acknowledge the contribution from this software where + * applicable, this list of conditions and the disclaimer below. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#include "arch/x86/bios/smbios.hh" +#include "arch/x86/isa_traits.hh" +#include "mem/port.hh" +#include "sim/byteswap.hh" +#include "sim/host.hh" + +const char X86ISA::SMBios::SMBiosTable::SMBiosHeader::anchorString[] = "_SM_"; +const uint8_t X86ISA::SMBios::SMBiosTable:: + SMBiosHeader::formattedArea[] = {0,0,0,0,0}; +const uint8_t X86ISA::SMBios::SMBiosTable:: + SMBiosHeader::entryPointLength = 0x1F; +const uint8_t X86ISA::SMBios::SMBiosTable:: + SMBiosHeader::entryPointRevision = 0; +const char X86ISA::SMBios::SMBiosTable:: + SMBiosHeader::IntermediateHeader::anchorString[] = "_DMI_"; + +uint16_t +X86ISA::SMBios::BiosInformation::writeOut(FunctionalPort * port, Addr addr) +{ + uint8_t size = SMBiosStructure::writeOut(port, addr); + + port->writeBlob(addr + 0x4, (uint8_t *)(&vendor), 1); + port->writeBlob(addr + 0x5, (uint8_t *)(&version), 1); + + uint16_t startingAddrSegmentGuest = X86ISA::htog(startingAddrSegment); + port->writeBlob(addr + 0x6, (uint8_t *)(&startingAddrSegmentGuest), 2); + + port->writeBlob(addr + 0x8, (uint8_t *)(&releaseDate), 1); + port->writeBlob(addr + 0x9, (uint8_t *)(&romSize), 1); + + uint64_t characteristicsGuest = X86ISA::htog(characteristics); + port->writeBlob(addr + 0xA, (uint8_t *)(&characteristicsGuest), 8); + + uint16_t characteristicExtBytesGuest = + X86ISA::htog(characteristicExtBytes); + port->writeBlob(addr + 0x12, (uint8_t *)(&characteristicExtBytesGuest), 2); + + port->writeBlob(addr + 0x14, (uint8_t *)(&major), 1); + port->writeBlob(addr + 0x15, (uint8_t *)(&minor), 1); + port->writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1); + port->writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1); + + writeOutStrings(port, addr + getLength()); + + return size; +} + +void +X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr) +{ + + /* + * The main header + */ + uint8_t mainChecksum = 0; + + port->writeBlob(addr, (uint8_t *)smbiosHeader.anchorString, 4); + for (int i = 0; i < 4; i++) + mainChecksum += smbiosHeader.anchorString[i]; + + // The checksum goes here, but we're figuring it out as we go. + + port->writeBlob(addr + 0x5, + (uint8_t *)(&smbiosHeader.entryPointLength), 1); + mainChecksum += smbiosHeader.entryPointLength; + port->writeBlob(addr + 0x6, + (uint8_t *)(&smbiosHeader.majorVersion), 1); + mainChecksum += smbiosHeader.majorVersion; + port->writeBlob(addr + 0x7, + (uint8_t *)(&smbiosHeader.minorVersion), 1); + mainChecksum += smbiosHeader.minorVersion; + // Maximum structure size goes here, but we'll figure it out later. + port->writeBlob(addr + 0xA, + (uint8_t *)(&smbiosHeader.entryPointRevision), 1); + mainChecksum += smbiosHeader.entryPointRevision; + port->writeBlob(addr + 0xB, + (uint8_t *)(&smbiosHeader.formattedArea), 5); + for (int i = 0; i < 5; i++) + mainChecksum += smbiosHeader.formattedArea[i]; + + /* + * The intermediate header + */ + uint8_t intChecksum = 0; + + port->writeBlob(addr + 0x10, + (uint8_t *)smbiosHeader.intermediateHeader.anchorString, 5); + for (int i = 0; i < 5; i++) + intChecksum += smbiosHeader.intermediateHeader.anchorString[i]; + + // The checksum goes here, but we're figuring it out as we go. + // Then the length of the structure table which we'll find later + + uint32_t tableAddrGuest = + X86ISA::htog(smbiosHeader.intermediateHeader.tableAddr); + port->writeBlob(addr + 0x18, (uint8_t *)(&tableAddrGuest), 4); + for (int i = 0; i < 4; i++) { + intChecksum += tableAddrGuest; + tableAddrGuest >>= 8; + } + + uint16_t numStructs = X86ISA::gtoh(structures.size()); + port->writeBlob(addr + 0x1C, (uint8_t *)(&numStructs), 2); + for (int i = 0; i < 2; i++) { + intChecksum += numStructs; + numStructs >>= 8; + } + + port->writeBlob(addr + 0x1E, + (uint8_t *)(&smbiosHeader.intermediateHeader.smbiosBCDRevision), + 1); + intChecksum += smbiosHeader.intermediateHeader.smbiosBCDRevision; + + /* + * Structure table + */ + + Addr base = smbiosHeader.intermediateHeader.tableAddr; + Addr offset = 0; + uint16_t maxSize = 0; + std::vector::iterator it; + for (it = structures.begin(); it != structures.end(); it++) { + uint16_t size = it->writeOut(port, base + offset); + if (size > maxSize) + maxSize = size; + offset += size; + } + + /* + * Header + */ + + maxSize = X86ISA::htog(maxSize); + port->writeBlob(addr + 0x8, (uint8_t *)(&maxSize), 2); + for (int i = 0; i < 2; i++) { + mainChecksum += maxSize; + maxSize >>= 8; + } + + // Set the checksum + mainChecksum = -mainChecksum; + port->writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1); + + /* + * Intermediate header + */ + + uint16_t tableSize = offset; + tableSize = X86ISA::htog(tableSize); + port->writeBlob(addr + 0x16, (uint8_t *)(&tableSize), 2); + for (int i = 0; i < 2; i++) { + intChecksum += tableSize; + tableSize >>= 8; + } + + intChecksum = -intChecksum; + port->writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1); +} diff --git a/src/arch/x86/bios/smbios.hh b/src/arch/x86/bios/smbios.hh new file mode 100644 index 000000000..8d3994fc7 --- /dev/null +++ b/src/arch/x86/bios/smbios.hh @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2008 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +/* + * Copyright (c) 2008 The Hewlett-Packard Development Company + * All rights reserved. + * + * Redistribution and use of this software in source and binary forms, + * with or without modification, are permitted provided that the + * following conditions are met: + * + * The software must be used only for Non-Commercial Use which means any + * use which is NOT directed to receiving any direct monetary + * compensation for, or commercial advantage from such use. Illustrative + * examples of non-commercial use are academic research, personal study, + * teaching, education and corporate research & development. + * Illustrative examples of commercial use are distributing products for + * commercial advantage and providing services using the software for + * commercial advantage. + * + * If you wish to use this software or functionality therein that may be + * covered by patents for commercial use, please contact: + * Director of Intellectual Property Licensing + * Office of Strategy and Technology + * Hewlett-Packard Company + * 1501 Page Mill Road + * Palo Alto, California 94304 + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. Redistributions + * in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. Neither the name of + * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. No right of + * sublicense is granted herewith. Derivatives of the software and + * output created using the software may be prepared, but only for + * Non-Commercial Uses. Derivatives of the software may be shared with + * others provided: (i) the others agree to abide by the list of + * conditions herein which includes the Non-Commercial Use restrictions; + * and (ii) such Derivatives of the software include the above copyright + * notice to acknowledge the contribution from this software where + * applicable, this list of conditions and the disclaimer below. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef __ARCH_X86_BIOS_SMBIOS_HH__ +#define __ARCH_X86_BIOS_SMBIOS_HH__ + +#include +#include + +#include "arch/x86/isa_traits.hh" +#include "mem/port.hh" +#include "sim/byteswap.hh" +#include "sim/host.hh" + +namespace X86ISA +{ + +namespace SMBios +{ + +class SMBiosStructure +{ + public: + + virtual + ~SMBiosStructure() + {} + + // Offset 00h, 1 byte + uint8_t type; + + // Offset 01h, 1 byte + //Length: computed when written to memory. + + // Offset 02h, 2 bytes + uint16_t handle; + + virtual uint8_t + getLength() + { + // This is the size of a structure with nothing but the header + return 4; + } + + virtual uint16_t + writeOut(FunctionalPort * port, Addr addr) + { + port->writeBlob(addr, (uint8_t *)(&type), 1); + + uint8_t length = getLength(); + port->writeBlob(addr + 1, (uint8_t *)(&length), 1); + + uint16_t handleGuest = X86ISA::htog(handle); + port->writeBlob(addr + 2, (uint8_t *)(&handleGuest), 2); + + return length + getStringLength(); + } + + protected: + std::vector strings; + + void writeOutStrings(FunctionalPort * port, Addr addr) + { + std::vector::iterator it; + Addr offset = 0; + + for (it = strings.begin(); it != strings.end(); it++) { + port->writeBlob(addr + offset, + (uint8_t *)it->c_str(), it->length() + 1); + offset += it->length() + 1; + } + + const uint8_t nullTerminator = 0; + port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1); + } + + int getStringLength() + { + int size = 0; + std::vector::iterator it; + + for (it = strings.begin(); it != strings.end(); it++) { + size += it->length() + 1; + } + + return size + 1; + } + + public: + + int addString(std::string & newString) + { + strings.push_back(newString); + return strings.size(); + } + + std::string readString(int n) + { + assert(n > 0 && n <= strings.size()); + return strings[n - 1]; + } + + void setString(int n, std::string & newString) + { + assert(n > 0 && n <= strings.size()); + strings[n - 1] = newString; + } +}; + +class BiosInformation : public SMBiosStructure +{ + public: + // Offset 04h, 1 byte + uint8_t vendor; + // Offset 05h, 1 byte + uint8_t version; + // Offset 06h, 2 bytes + uint16_t startingAddrSegment; + // Offset 08h, 1 byte + uint8_t releaseDate; + // Offset 09h, 1 byte + uint8_t romSize; + // Offset 0Ah, 8 bytes + //See tables in 3.3.1 in the SMBios 2.5 spec from the DMTF for + //bit definitions. + uint64_t characteristics; + // Offset 12h, 2 bytes + uint16_t characteristicExtBytes; + // Offset 14h, 1 byte + uint8_t major; + // Offset 15h, 1 byte + uint8_t minor; + // Offset 16h, 1 byte + uint8_t embContFirmwareMajor; + // Offset 17h, 1 byte + uint8_t embContFirmwareMinor; + + uint8_t getLength() { return 0x18; } + uint16_t writeOut(FunctionalPort * port, Addr addr); +}; + +class SMBiosTable +{ + public: + struct SMBiosHeader + { + SMBiosHeader() + {} + + // Offset 00h, 4 bytes + static const char anchorString[]; + + // Offset 04h, 1 byte + //Checksum: computed when written to memory. + + // Offset 05h, 1 byte + static const uint8_t entryPointLength; + + // Offset 06h, 1 byte + uint8_t majorVersion; + + // Offset 07h, 1 byte + uint8_t minorVersion; + + // Offset 08h, 2 bytes + //Maximum structure size: computed when written to memory. + + // Offset 0Ah, 1 byte + static const uint8_t entryPointRevision; + + // Offset 0Bh, 5 bytes + static const uint8_t formattedArea[5]; + + // Offset 10h, 15 bytes + struct IntermediateHeader + { + IntermediateHeader() : tableAddr(0) + {} + // Offset 10h, 5 bytes + static const char anchorString[]; + + // Offset 15h, 1 byte + //Checksum: computed when written to memory. + + // Offset 16h, 2 bytes + //Length of the structure table in bytes: computed when + //written to memory. + + // Offset 18h, 4 bytes + uint32_t tableAddr; + + // Offset 1Ch, 2 bytes + //Number of structures: computed when written to memory + + // Offset 1Eh, 1 byte + uint8_t smbiosBCDRevision; + } intermediateHeader; + } smbiosHeader; + + void writeOut(FunctionalPort * port, Addr addr); + + std::vector structures; +}; + +} //SMBios +} //X86ISA + +#endif diff --git a/src/arch/x86/smbios.cc b/src/arch/x86/smbios.cc deleted file mode 100644 index 319650c1f..000000000 --- a/src/arch/x86/smbios.cc +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (c) 2008 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Gabe Black - */ - -/* - * Copyright (c) 2008 The Hewlett-Packard Development Company - * All rights reserved. - * - * Redistribution and use of this software in source and binary forms, - * with or without modification, are permitted provided that the - * following conditions are met: - * - * The software must be used only for Non-Commercial Use which means any - * use which is NOT directed to receiving any direct monetary - * compensation for, or commercial advantage from such use. Illustrative - * examples of non-commercial use are academic research, personal study, - * teaching, education and corporate research & development. - * Illustrative examples of commercial use are distributing products for - * commercial advantage and providing services using the software for - * commercial advantage. - * - * If you wish to use this software or functionality therein that may be - * covered by patents for commercial use, please contact: - * Director of Intellectual Property Licensing - * Office of Strategy and Technology - * Hewlett-Packard Company - * 1501 Page Mill Road - * Palo Alto, California 94304 - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. Redistributions - * in binary form must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. Neither the name of - * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. No right of - * sublicense is granted herewith. Derivatives of the software and - * output created using the software may be prepared, but only for - * Non-Commercial Uses. Derivatives of the software may be shared with - * others provided: (i) the others agree to abide by the list of - * conditions herein which includes the Non-Commercial Use restrictions; - * and (ii) such Derivatives of the software include the above copyright - * notice to acknowledge the contribution from this software where - * applicable, this list of conditions and the disclaimer below. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Gabe Black - */ - -#include "arch/x86/smbios.hh" -#include "arch/x86/isa_traits.hh" -#include "mem/port.hh" -#include "sim/byteswap.hh" -#include "sim/host.hh" - -const char X86ISA::SMBios::SMBiosTable::SMBiosHeader::anchorString[] = "_SM_"; -const uint8_t X86ISA::SMBios::SMBiosTable:: - SMBiosHeader::formattedArea[] = {0,0,0,0,0}; -const uint8_t X86ISA::SMBios::SMBiosTable:: - SMBiosHeader::entryPointLength = 0x1F; -const uint8_t X86ISA::SMBios::SMBiosTable:: - SMBiosHeader::entryPointRevision = 0; -const char X86ISA::SMBios::SMBiosTable:: - SMBiosHeader::IntermediateHeader::anchorString[] = "_DMI_"; - -uint16_t -X86ISA::SMBios::BiosInformation::writeOut(FunctionalPort * port, Addr addr) -{ - uint8_t size = SMBiosStructure::writeOut(port, addr); - - port->writeBlob(addr + 0x4, (uint8_t *)(&vendor), 1); - port->writeBlob(addr + 0x5, (uint8_t *)(&version), 1); - - uint16_t startingAddrSegmentGuest = X86ISA::htog(startingAddrSegment); - port->writeBlob(addr + 0x6, (uint8_t *)(&startingAddrSegmentGuest), 2); - - port->writeBlob(addr + 0x8, (uint8_t *)(&releaseDate), 1); - port->writeBlob(addr + 0x9, (uint8_t *)(&romSize), 1); - - uint64_t characteristicsGuest = X86ISA::htog(characteristics); - port->writeBlob(addr + 0xA, (uint8_t *)(&characteristicsGuest), 8); - - uint16_t characteristicExtBytesGuest = - X86ISA::htog(characteristicExtBytes); - port->writeBlob(addr + 0x12, (uint8_t *)(&characteristicExtBytesGuest), 2); - - port->writeBlob(addr + 0x14, (uint8_t *)(&major), 1); - port->writeBlob(addr + 0x15, (uint8_t *)(&minor), 1); - port->writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1); - port->writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1); - - writeOutStrings(port, addr + getLength()); - - return size; -} - -void -X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr) -{ - - /* - * The main header - */ - uint8_t mainChecksum = 0; - - port->writeBlob(addr, (uint8_t *)smbiosHeader.anchorString, 4); - for (int i = 0; i < 4; i++) - mainChecksum += smbiosHeader.anchorString[i]; - - // The checksum goes here, but we're figuring it out as we go. - - port->writeBlob(addr + 0x5, - (uint8_t *)(&smbiosHeader.entryPointLength), 1); - mainChecksum += smbiosHeader.entryPointLength; - port->writeBlob(addr + 0x6, - (uint8_t *)(&smbiosHeader.majorVersion), 1); - mainChecksum += smbiosHeader.majorVersion; - port->writeBlob(addr + 0x7, - (uint8_t *)(&smbiosHeader.minorVersion), 1); - mainChecksum += smbiosHeader.minorVersion; - // Maximum structure size goes here, but we'll figure it out later. - port->writeBlob(addr + 0xA, - (uint8_t *)(&smbiosHeader.entryPointRevision), 1); - mainChecksum += smbiosHeader.entryPointRevision; - port->writeBlob(addr + 0xB, - (uint8_t *)(&smbiosHeader.formattedArea), 5); - for (int i = 0; i < 5; i++) - mainChecksum += smbiosHeader.formattedArea[i]; - - /* - * The intermediate header - */ - uint8_t intChecksum = 0; - - port->writeBlob(addr + 0x10, - (uint8_t *)smbiosHeader.intermediateHeader.anchorString, 5); - for (int i = 0; i < 5; i++) - intChecksum += smbiosHeader.intermediateHeader.anchorString[i]; - - // The checksum goes here, but we're figuring it out as we go. - // Then the length of the structure table which we'll find later - - uint32_t tableAddrGuest = - X86ISA::htog(smbiosHeader.intermediateHeader.tableAddr); - port->writeBlob(addr + 0x18, (uint8_t *)(&tableAddrGuest), 4); - for (int i = 0; i < 4; i++) { - intChecksum += tableAddrGuest; - tableAddrGuest >>= 8; - } - - uint16_t numStructs = X86ISA::gtoh(structures.size()); - port->writeBlob(addr + 0x1C, (uint8_t *)(&numStructs), 2); - for (int i = 0; i < 2; i++) { - intChecksum += numStructs; - numStructs >>= 8; - } - - port->writeBlob(addr + 0x1E, - (uint8_t *)(&smbiosHeader.intermediateHeader.smbiosBCDRevision), - 1); - intChecksum += smbiosHeader.intermediateHeader.smbiosBCDRevision; - - /* - * Structure table - */ - - Addr base = smbiosHeader.intermediateHeader.tableAddr; - Addr offset = 0; - uint16_t maxSize = 0; - std::vector::iterator it; - for (it = structures.begin(); it != structures.end(); it++) { - uint16_t size = it->writeOut(port, base + offset); - if (size > maxSize) - maxSize = size; - offset += size; - } - - /* - * Header - */ - - maxSize = X86ISA::htog(maxSize); - port->writeBlob(addr + 0x8, (uint8_t *)(&maxSize), 2); - for (int i = 0; i < 2; i++) { - mainChecksum += maxSize; - maxSize >>= 8; - } - - // Set the checksum - mainChecksum = -mainChecksum; - port->writeBlob(addr + 0x4, (uint8_t *)(&mainChecksum), 1); - - /* - * Intermediate header - */ - - uint16_t tableSize = offset; - tableSize = X86ISA::htog(tableSize); - port->writeBlob(addr + 0x16, (uint8_t *)(&tableSize), 2); - for (int i = 0; i < 2; i++) { - intChecksum += tableSize; - tableSize >>= 8; - } - - intChecksum = -intChecksum; - port->writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1); -} diff --git a/src/arch/x86/smbios.hh b/src/arch/x86/smbios.hh deleted file mode 100644 index c126de220..000000000 --- a/src/arch/x86/smbios.hh +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright (c) 2008 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Gabe Black - */ - -/* - * Copyright (c) 2008 The Hewlett-Packard Development Company - * All rights reserved. - * - * Redistribution and use of this software in source and binary forms, - * with or without modification, are permitted provided that the - * following conditions are met: - * - * The software must be used only for Non-Commercial Use which means any - * use which is NOT directed to receiving any direct monetary - * compensation for, or commercial advantage from such use. Illustrative - * examples of non-commercial use are academic research, personal study, - * teaching, education and corporate research & development. - * Illustrative examples of commercial use are distributing products for - * commercial advantage and providing services using the software for - * commercial advantage. - * - * If you wish to use this software or functionality therein that may be - * covered by patents for commercial use, please contact: - * Director of Intellectual Property Licensing - * Office of Strategy and Technology - * Hewlett-Packard Company - * 1501 Page Mill Road - * Palo Alto, California 94304 - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. Redistributions - * in binary form must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. Neither the name of - * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. No right of - * sublicense is granted herewith. Derivatives of the software and - * output created using the software may be prepared, but only for - * Non-Commercial Uses. Derivatives of the software may be shared with - * others provided: (i) the others agree to abide by the list of - * conditions herein which includes the Non-Commercial Use restrictions; - * and (ii) such Derivatives of the software include the above copyright - * notice to acknowledge the contribution from this software where - * applicable, this list of conditions and the disclaimer below. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Gabe Black - */ - -#ifndef __ARCH_X86_SMBIOS_HH__ -#define __ARCH_X86_SMBIOS_HH__ - -#include -#include - -#include "arch/x86/isa_traits.hh" -#include "mem/port.hh" -#include "sim/byteswap.hh" -#include "sim/host.hh" - -namespace X86ISA -{ - -namespace SMBios -{ - -class SMBiosStructure -{ - public: - - virtual - ~SMBiosStructure() - {} - - // Offset 00h, 1 byte - uint8_t type; - - // Offset 01h, 1 byte - //Length: computed when written to memory. - - // Offset 02h, 2 bytes - uint16_t handle; - - virtual uint8_t - getLength() - { - // This is the size of a structure with nothing but the header - return 4; - } - - virtual uint16_t - writeOut(FunctionalPort * port, Addr addr) - { - port->writeBlob(addr, (uint8_t *)(&type), 1); - - uint8_t length = getLength(); - port->writeBlob(addr + 1, (uint8_t *)(&length), 1); - - uint16_t handleGuest = X86ISA::htog(handle); - port->writeBlob(addr + 2, (uint8_t *)(&handleGuest), 2); - - return length + getStringLength(); - } - - protected: - std::vector strings; - - void writeOutStrings(FunctionalPort * port, Addr addr) - { - std::vector::iterator it; - Addr offset = 0; - - for (it = strings.begin(); it != strings.end(); it++) { - port->writeBlob(addr + offset, - (uint8_t *)it->c_str(), it->length() + 1); - offset += it->length() + 1; - } - - const uint8_t nullTerminator = 0; - port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1); - } - - int getStringLength() - { - int size = 0; - std::vector::iterator it; - - for (it = strings.begin(); it != strings.end(); it++) { - size += it->length() + 1; - } - - return size + 1; - } - - public: - - int addString(std::string & newString) - { - strings.push_back(newString); - return strings.size(); - } - - std::string readString(int n) - { - assert(n > 0 && n <= strings.size()); - return strings[n - 1]; - } - - void setString(int n, std::string & newString) - { - assert(n > 0 && n <= strings.size()); - strings[n - 1] = newString; - } -}; - -class BiosInformation : public SMBiosStructure -{ - public: - // Offset 04h, 1 byte - uint8_t vendor; - // Offset 05h, 1 byte - uint8_t version; - // Offset 06h, 2 bytes - uint16_t startingAddrSegment; - // Offset 08h, 1 byte - uint8_t releaseDate; - // Offset 09h, 1 byte - uint8_t romSize; - // Offset 0Ah, 8 bytes - //See tables in 3.3.1 in the SMBios 2.5 spec from the DMTF for - //bit definitions. - uint64_t characteristics; - // Offset 12h, 2 bytes - uint16_t characteristicExtBytes; - // Offset 14h, 1 byte - uint8_t major; - // Offset 15h, 1 byte - uint8_t minor; - // Offset 16h, 1 byte - uint8_t embContFirmwareMajor; - // Offset 17h, 1 byte - uint8_t embContFirmwareMinor; - - uint8_t getLength() { return 0x18; } - uint16_t writeOut(FunctionalPort * port, Addr addr); -}; - -class SMBiosTable -{ - public: - struct SMBiosHeader - { - SMBiosHeader() - {} - - // Offset 00h, 4 bytes - static const char anchorString[]; - - // Offset 04h, 1 byte - //Checksum: computed when written to memory. - - // Offset 05h, 1 byte - static const uint8_t entryPointLength; - - // Offset 06h, 1 byte - uint8_t majorVersion; - - // Offset 07h, 1 byte - uint8_t minorVersion; - - // Offset 08h, 2 bytes - //Maximum structure size: computed when written to memory. - - // Offset 0Ah, 1 byte - static const uint8_t entryPointRevision; - - // Offset 0Bh, 5 bytes - static const uint8_t formattedArea[5]; - - // Offset 10h, 15 bytes - struct IntermediateHeader - { - IntermediateHeader() : tableAddr(0) - {} - // Offset 10h, 5 bytes - static const char anchorString[]; - - // Offset 15h, 1 byte - //Checksum: computed when written to memory. - - // Offset 16h, 2 bytes - //Length of the structure table in bytes: computed when - //written to memory. - - // Offset 18h, 4 bytes - uint32_t tableAddr; - - // Offset 1Ch, 2 bytes - //Number of structures: computed when written to memory - - // Offset 1Eh, 1 byte - uint8_t smbiosBCDRevision; - } intermediateHeader; - } smbiosHeader; - - void writeOut(FunctionalPort * port, Addr addr); - - std::vector structures; -}; - -} //SMBios -} //X86ISA - -#endif diff --git a/src/arch/x86/system.cc b/src/arch/x86/system.cc index 947a7793e..48f34918d 100644 --- a/src/arch/x86/system.cc +++ b/src/arch/x86/system.cc @@ -55,9 +55,9 @@ * Authors: Gabe Black */ +#include "arch/x86/bios/smbios.hh" #include "arch/x86/miscregs.hh" #include "arch/x86/system.hh" -#include "arch/x86/smbios.hh" #include "arch/vtophys.hh" #include "base/remote_gdb.hh" #include "base/loader/object_file.hh" -- cgit v1.2.3 From 9be6e082270aad53f8ba40bf66a91fcf176a45ab Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 10 Oct 2008 03:50:42 -0700 Subject: X86: Add a couple comments to the bios SConscript --- src/arch/x86/bios/SConscript | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/bios/SConscript b/src/arch/x86/bios/SConscript index 904fab086..1ec717b11 100644 --- a/src/arch/x86/bios/SConscript +++ b/src/arch/x86/bios/SConscript @@ -59,7 +59,10 @@ Import('*') if env['TARGET_ISA'] == 'x86': if env['FULL_SYSTEM']: + # The table generated by the bootloader using the BIOS and passed to + # the operating system which maps out physical memory. SimObject('E820.py') Source('e820.cc') + # The DMI tables. Source('smbios.cc') -- cgit v1.2.3 From ec0fb05d643323ae036156be76acd42c8275a2f4 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 10 Oct 2008 03:50:51 -0700 Subject: X86: Turn SMBios structures into simobjects. --- src/arch/x86/X86System.py | 3 + src/arch/x86/bios/SConscript | 1 + src/arch/x86/bios/SMBios.py | 140 +++++++++++++++++++++++++++++++++++++++ src/arch/x86/bios/smbios.cc | 152 +++++++++++++++++++++++++++++++++++++++++-- src/arch/x86/bios/smbios.hh | 114 ++++++++++++++------------------ src/arch/x86/system.cc | 35 +++++----- src/arch/x86/system.hh | 3 +- 7 files changed, 361 insertions(+), 87 deletions(-) create mode 100644 src/arch/x86/bios/SMBios.py (limited to 'src/arch') diff --git a/src/arch/x86/X86System.py b/src/arch/x86/X86System.py index b4ec393c3..5fe69c709 100644 --- a/src/arch/x86/X86System.py +++ b/src/arch/x86/X86System.py @@ -55,10 +55,13 @@ from m5.params import * from E820 import X86E820Table, X86E820Entry +from SMBios import X86SMBiosSMBiosTable from System import System class X86System(System): type = 'X86System' + smbios_table = Param.X86SMBiosSMBiosTable( + X86SMBiosSMBiosTable(), 'table of smbios/dmi information') class LinuxX86System(X86System): type = 'LinuxX86System' diff --git a/src/arch/x86/bios/SConscript b/src/arch/x86/bios/SConscript index 1ec717b11..cdb5f390f 100644 --- a/src/arch/x86/bios/SConscript +++ b/src/arch/x86/bios/SConscript @@ -65,4 +65,5 @@ if env['TARGET_ISA'] == 'x86': Source('e820.cc') # The DMI tables. + SimObject('SMBios.py') Source('smbios.cc') diff --git a/src/arch/x86/bios/SMBios.py b/src/arch/x86/bios/SMBios.py new file mode 100644 index 000000000..4947b2854 --- /dev/null +++ b/src/arch/x86/bios/SMBios.py @@ -0,0 +1,140 @@ +# Copyright (c) 2008 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use of this software in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# +# The software must be used only for Non-Commercial Use which means any +# use which is NOT directed to receiving any direct monetary +# compensation for, or commercial advantage from such use. Illustrative +# examples of non-commercial use are academic research, personal study, +# teaching, education and corporate research & development. +# Illustrative examples of commercial use are distributing products for +# commercial advantage and providing services using the software for +# commercial advantage. +# +# If you wish to use this software or functionality therein that may be +# covered by patents for commercial use, please contact: +# Director of Intellectual Property Licensing +# Office of Strategy and Technology +# Hewlett-Packard Company +# 1501 Page Mill Road +# Palo Alto, California 94304 +# +# Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. Redistributions +# in binary form must reproduce the above copyright notice, this list of +# conditions and the following disclaimer in the documentation and/or +# other materials provided with the distribution. Neither the name of +# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. No right of +# sublicense is granted herewith. Derivatives of the software and +# output created using the software may be prepared, but only for +# Non-Commercial Uses. Derivatives of the software may be shared with +# others provided: (i) the others agree to abide by the list of +# conditions herein which includes the Non-Commercial Use restrictions; +# and (ii) such Derivatives of the software include the above copyright +# notice to acknowledge the contribution from this software where +# applicable, this list of conditions and the disclaimer below. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Gabe Black + +from m5.params import * +from m5.SimObject import SimObject + +class X86SMBiosSMBiosStructure(SimObject): + type = 'X86SMBiosSMBiosStructure' + cxx_class = 'X86ISA::SMBios::SMBiosStructure' + abstract = True + +class Characteristic(Enum): + map = {'Unknown' : 2, + 'Unsupported' : 3, + 'ISA' : 4, + 'MCA' : 5, + 'EISA' : 6, + 'PCI' : 7, + 'PCMCIA' : 8, + 'PnP' : 9, + 'APM' : 10, + 'Flash' : 11, + 'Shadow' : 12, + 'VL_Vesa' : 13, + 'ESCD' : 14, + 'CDBoot' : 15, + 'SelectBoot' : 16, + 'Socketed' : 17, + 'PCMCIABoot' : 18, + 'EDD' : 19, + 'NEC9800' : 20, + 'Toshiba' : 21, + 'Floppy_5_25_360KB' : 22, + 'Floppy_5_25_1_2MB' : 23, + 'Floppy_3_5_720KB' : 24, + 'Floppy_3_5_2_88MB' : 25, + 'PrintScreen' : 26, + 'Keyboard8024' : 27, + 'Serial' : 28, + 'Printer' : 29, + 'CGA_Mono' : 30, + 'NEC_PC_98' : 31 + } + +class ExtCharacteristic(Enum): + map = {'ACPI' : 0, + 'USBLegacy' : 1, + 'AGP' : 2, + 'I20Boot' : 3, + 'LS_120Boot' : 4, + 'ZIPBoot' : 5, + 'FirewireBoot' : 6, + 'SmartBattery' : 7, + 'BootSpec' : 8, + 'NetServiceBoot' : 9, + 'TargetContent' : 10 + } + +class X86SMBiosBiosInformation(X86SMBiosSMBiosStructure): + type = 'X86SMBiosBiosInformation' + cxx_class = 'X86ISA::SMBios::BiosInformation' + + vendor = Param.String("", "vendor name string") + version = Param.String("", "version string") + starting_addr_segment = \ + Param.UInt16(0, "segment location of bios starting address") + release_date = Param.String("06/08/2008", "release date") + rom_size = Param.UInt8(0, "rom size") + characteristics = VectorParam.Characteristic([], + "bios characteristic bit vector") + characteristic_ext_bytes = VectorParam.ExtCharacteristic([], + "extended bios characteristic bit vector") + major = Param.UInt8(0, "major version number") + minor = Param.UInt8(0, "minor version number") + emb_cont_firmware_major = Param.UInt8(0, + "embedded controller firmware major version number") + + emb_cont_firmware_minor = Param.UInt8(0, + "embedded controller firmware minor version number") + +class X86SMBiosSMBiosTable(SimObject): + type = 'X86SMBiosSMBiosTable' + cxx_class = 'X86ISA::SMBios::SMBiosTable' + + major_version = Param.UInt8(2, "major version number") + minor_version = Param.UInt8(5, "minor version number") + + structures = VectorParam.X86SMBiosSMBiosStructure([], "smbios structures") diff --git a/src/arch/x86/bios/smbios.cc b/src/arch/x86/bios/smbios.cc index de4a263b7..95ade1e4d 100644 --- a/src/arch/x86/bios/smbios.cc +++ b/src/arch/x86/bios/smbios.cc @@ -88,9 +88,14 @@ #include "arch/x86/bios/smbios.hh" #include "arch/x86/isa_traits.hh" #include "mem/port.hh" +#include "params/X86SMBiosBiosInformation.hh" +#include "params/X86SMBiosSMBiosStructure.hh" +#include "params/X86SMBiosSMBiosTable.hh" #include "sim/byteswap.hh" #include "sim/host.hh" +using namespace std; + const char X86ISA::SMBios::SMBiosTable::SMBiosHeader::anchorString[] = "_SM_"; const uint8_t X86ISA::SMBios::SMBiosTable:: SMBiosHeader::formattedArea[] = {0,0,0,0,0}; @@ -101,6 +106,116 @@ const uint8_t X86ISA::SMBios::SMBiosTable:: const char X86ISA::SMBios::SMBiosTable:: SMBiosHeader::IntermediateHeader::anchorString[] = "_DMI_"; +template +uint64_t +composeBitVector(T vec) +{ + uint64_t val = 0; + typename T::iterator vecIt; + for (vecIt = vec.begin(); vecIt != vec.end(); vecIt++) { + val |= (1 << (*vecIt)); + } + return val; +} + +uint16_t +X86ISA::SMBios::SMBiosStructure::writeOut(FunctionalPort * port, Addr addr) +{ + port->writeBlob(addr, (uint8_t *)(&type), 1); + + uint8_t length = getLength(); + port->writeBlob(addr + 1, (uint8_t *)(&length), 1); + + uint16_t handleGuest = X86ISA::htog(handle); + port->writeBlob(addr + 2, (uint8_t *)(&handleGuest), 2); + + return length + getStringLength(); +} + +X86ISA::SMBios::SMBiosStructure::SMBiosStructure(Params * p, uint8_t _type) : + SimObject(p), type(_type), handle(0), stringFields(false) +{} + +void +X86ISA::SMBios::SMBiosStructure::writeOutStrings( + FunctionalPort * port, Addr addr) +{ + std::vector::iterator it; + Addr offset = 0; + + const uint8_t nullTerminator = 0; + + // If there are string fields but none of them are used, that's a + // special case which is handled by this if. + if (strings.size() == 0 && stringFields) { + port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1); + offset++; + } else { + for (it = strings.begin(); it != strings.end(); it++) { + port->writeBlob(addr + offset, + (uint8_t *)it->c_str(), it->length() + 1); + offset += it->length() + 1; + } + } + port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1); +} + +int +X86ISA::SMBios::SMBiosStructure::getStringLength() +{ + int size = 0; + std::vector::iterator it; + + for (it = strings.begin(); it != strings.end(); it++) { + size += it->length() + 1; + } + + return size + 1; +} + +int +X86ISA::SMBios::SMBiosStructure::addString(string & newString) +{ + stringFields = true; + // If a string is empty, treat it as not existing. The index for empty + // strings is 0. + if (newString.length() == 0) + return 0; + strings.push_back(newString); + return strings.size(); +} + +string +X86ISA::SMBios::SMBiosStructure::readString(int n) +{ + assert(n > 0 && n <= strings.size()); + return strings[n - 1]; +} + +void +X86ISA::SMBios::SMBiosStructure::setString(int n, std::string & newString) +{ + assert(n > 0 && n <= strings.size()); + strings[n - 1] = newString; +} + +X86ISA::SMBios::BiosInformation::BiosInformation(Params * p) : + SMBiosStructure(p, Type), + startingAddrSegment(p->starting_addr_segment), + romSize(p->rom_size), + majorVer(p->major), minorVer(p->minor), + embContFirmwareMajor(p->emb_cont_firmware_major), + embContFirmwareMinor(p->emb_cont_firmware_minor) + { + vendor = addString(p->vendor); + version = addString(p->version); + releaseDate = addString(p->release_date); + + characteristics = composeBitVector(p->characteristics); + characteristicExtBytes = + composeBitVector(p->characteristic_ext_bytes); + } + uint16_t X86ISA::SMBios::BiosInformation::writeOut(FunctionalPort * port, Addr addr) { @@ -122,8 +237,8 @@ X86ISA::SMBios::BiosInformation::writeOut(FunctionalPort * port, Addr addr) X86ISA::htog(characteristicExtBytes); port->writeBlob(addr + 0x12, (uint8_t *)(&characteristicExtBytesGuest), 2); - port->writeBlob(addr + 0x14, (uint8_t *)(&major), 1); - port->writeBlob(addr + 0x15, (uint8_t *)(&minor), 1); + port->writeBlob(addr + 0x14, (uint8_t *)(&majorVer), 1); + port->writeBlob(addr + 0x15, (uint8_t *)(&minorVer), 1); port->writeBlob(addr + 0x16, (uint8_t *)(&embContFirmwareMajor), 1); port->writeBlob(addr + 0x17, (uint8_t *)(&embContFirmwareMinor), 1); @@ -132,9 +247,22 @@ X86ISA::SMBios::BiosInformation::writeOut(FunctionalPort * port, Addr addr) return size; } +X86ISA::SMBios::SMBiosTable::SMBiosTable(Params * p) : + SimObject(p), structures(p->structures) +{ + smbiosHeader.majorVersion = p->major_version; + smbiosHeader.minorVersion = p->minor_version; + assert(p->major_version <= 9); + assert(p->minor_version <= 9); + smbiosHeader.intermediateHeader.smbiosBCDRevision = + (p->major_version << 4) | p->minor_version; +} + void -X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr) +X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr, + Addr &headerSize, Addr &structSize) { + headerSize = 0x1F; /* * The main header @@ -205,14 +333,16 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr) Addr base = smbiosHeader.intermediateHeader.tableAddr; Addr offset = 0; uint16_t maxSize = 0; - std::vector::iterator it; + std::vector::iterator it; for (it = structures.begin(); it != structures.end(); it++) { - uint16_t size = it->writeOut(port, base + offset); + uint16_t size = (*it)->writeOut(port, base + offset); if (size > maxSize) maxSize = size; offset += size; } + structSize = offset; + /* * Header */ @@ -243,3 +373,15 @@ X86ISA::SMBios::SMBiosTable::writeOut(FunctionalPort * port, Addr addr) intChecksum = -intChecksum; port->writeBlob(addr + 0x15, (uint8_t *)(&intChecksum), 1); } + +X86ISA::SMBios::BiosInformation * +X86SMBiosBiosInformationParams::create() +{ + return new X86ISA::SMBios::BiosInformation(this); +} + +X86ISA::SMBios::SMBiosTable * +X86SMBiosSMBiosTableParams::create() +{ + return new X86ISA::SMBios::SMBiosTable(this); +} diff --git a/src/arch/x86/bios/smbios.hh b/src/arch/x86/bios/smbios.hh index 8d3994fc7..1c50d0b48 100644 --- a/src/arch/x86/bios/smbios.hh +++ b/src/arch/x86/bios/smbios.hh @@ -91,10 +91,15 @@ #include #include -#include "arch/x86/isa_traits.hh" -#include "mem/port.hh" -#include "sim/byteswap.hh" +#include "enums/Characteristic.hh" +#include "enums/ExtCharacteristic.hh" #include "sim/host.hh" +#include "sim/sim_object.hh" + +class FunctionalPort; +class X86SMBiosBiosInformationParams; +class X86SMBiosSMBiosStructureParams; +class X86SMBiosSMBiosTableParams; namespace X86ISA { @@ -102,8 +107,11 @@ namespace X86ISA namespace SMBios { -class SMBiosStructure +class SMBiosStructure : public SimObject { + protected: + typedef X86SMBiosSMBiosStructureParams Params; + public: virtual @@ -126,73 +134,33 @@ class SMBiosStructure return 4; } - virtual uint16_t - writeOut(FunctionalPort * port, Addr addr) - { - port->writeBlob(addr, (uint8_t *)(&type), 1); - - uint8_t length = getLength(); - port->writeBlob(addr + 1, (uint8_t *)(&length), 1); - - uint16_t handleGuest = X86ISA::htog(handle); - port->writeBlob(addr + 2, (uint8_t *)(&handleGuest), 2); - - return length + getStringLength(); - } + virtual uint16_t writeOut(FunctionalPort * port, Addr addr); protected: - std::vector strings; - - void writeOutStrings(FunctionalPort * port, Addr addr) - { - std::vector::iterator it; - Addr offset = 0; - - for (it = strings.begin(); it != strings.end(); it++) { - port->writeBlob(addr + offset, - (uint8_t *)it->c_str(), it->length() + 1); - offset += it->length() + 1; - } + bool stringFields; - const uint8_t nullTerminator = 0; - port->writeBlob(addr + offset, (uint8_t *)(&nullTerminator), 1); - } + SMBiosStructure(Params * p, uint8_t _type); - int getStringLength() - { - int size = 0; - std::vector::iterator it; + std::vector strings; - for (it = strings.begin(); it != strings.end(); it++) { - size += it->length() + 1; - } + void writeOutStrings(FunctionalPort * port, Addr addr); - return size + 1; - } + int getStringLength(); public: - int addString(std::string & newString) - { - strings.push_back(newString); - return strings.size(); - } - - std::string readString(int n) - { - assert(n > 0 && n <= strings.size()); - return strings[n - 1]; - } - - void setString(int n, std::string & newString) - { - assert(n > 0 && n <= strings.size()); - strings[n - 1] = newString; - } + int addString(std::string & newString); + std::string readString(int n); + void setString(int n, std::string & newString); }; class BiosInformation : public SMBiosStructure { + protected: + const static uint8_t Type = 0; + + typedef X86SMBiosBiosInformationParams Params; + public: // Offset 04h, 1 byte uint8_t vendor; @@ -211,21 +179,25 @@ class BiosInformation : public SMBiosStructure // Offset 12h, 2 bytes uint16_t characteristicExtBytes; // Offset 14h, 1 byte - uint8_t major; + uint8_t majorVer; // Offset 15h, 1 byte - uint8_t minor; + uint8_t minorVer; // Offset 16h, 1 byte uint8_t embContFirmwareMajor; // Offset 17h, 1 byte uint8_t embContFirmwareMinor; + BiosInformation(Params * p); + uint8_t getLength() { return 0x18; } uint16_t writeOut(FunctionalPort * port, Addr addr); }; -class SMBiosTable +class SMBiosTable : public SimObject { - public: + protected: + typedef X86SMBiosSMBiosTableParams Params; + struct SMBiosHeader { SMBiosHeader() @@ -281,9 +253,23 @@ class SMBiosTable } intermediateHeader; } smbiosHeader; - void writeOut(FunctionalPort * port, Addr addr); + std::vector structures; + + public: + SMBiosTable(Params * p); + + Addr getTableAddr() + { + return smbiosHeader.intermediateHeader.tableAddr; + } + + void setTableAddr(Addr addr) + { + smbiosHeader.intermediateHeader.tableAddr = addr; + } - std::vector structures; + void writeOut(FunctionalPort * port, Addr addr, + Addr &headerSize, Addr &structSize); }; } //SMBios diff --git a/src/arch/x86/system.cc b/src/arch/x86/system.cc index 48f34918d..9006ce227 100644 --- a/src/arch/x86/system.cc +++ b/src/arch/x86/system.cc @@ -73,13 +73,8 @@ using namespace LittleEndianGuest; using namespace X86ISA; X86System::X86System(Params *p) - : System(p) -{ - smbiosTable = new X86ISA::SMBios::SMBiosTable; - smbiosTable->smbiosHeader.majorVersion = 2; - smbiosTable->smbiosHeader.minorVersion = 5; - smbiosTable->smbiosHeader.intermediateHeader.smbiosBCDRevision = 0x25; -} + : System(p), smbiosTable(p->smbios_table) +{} void X86System::startup() @@ -236,27 +231,33 @@ X86System::startup() // We should now be in long mode. Yay! + Addr ebdaPos = 0xF0000; + + Addr headerSize, structSize; //Write out the SMBios/DMI table - writeOutSMBiosTable(0xF0000); + writeOutSMBiosTable(ebdaPos, headerSize, structSize); + ebdaPos += (headerSize + structSize); } void -X86System::writeOutSMBiosTable(Addr header, Addr table) +X86System::writeOutSMBiosTable(Addr header, + Addr &headerSize, Addr &structSize, Addr table) { // Get a port to write the table and header to memory. FunctionalPort * physPort = threadContexts[0]->getPhysPort(); // If the table location isn't specified, just put it after the header. // The header size as of the 2.5 SMBios specification is 0x1F bytes - if (!table) { - if (!smbiosTable->smbiosHeader.intermediateHeader.tableAddr) - smbiosTable->smbiosHeader. - intermediateHeader.tableAddr = header + 0x1F; - } else { - smbiosTable->smbiosHeader.intermediateHeader.tableAddr = table; - } + if (!table) + table = header + 0x1F; + smbiosTable->setTableAddr(table); + + smbiosTable->writeOut(physPort, header, headerSize, structSize); - smbiosTable->writeOut(physPort, header); + // Do some bounds checking to make sure we at least didn't step on + // ourselves. + assert(header > table || header + headerSize <= table); + assert(table > header || table + structSize <= header); } diff --git a/src/arch/x86/system.hh b/src/arch/x86/system.hh index 8a5483ebf..2120bc090 100644 --- a/src/arch/x86/system.hh +++ b/src/arch/x86/system.hh @@ -96,7 +96,8 @@ class X86System : public System X86ISA::SMBios::SMBiosTable * smbiosTable; - void writeOutSMBiosTable(Addr header, Addr table = 0); + void writeOutSMBiosTable(Addr header, + Addr &headerSize, Addr &tableSize, Addr table = 0); const Params *params() const { return (const Params *)_params; } -- cgit v1.2.3 From 5586b1539baf6dd9029473a4ec1596a9fc8b7765 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 10 Oct 2008 10:15:00 -0700 Subject: misc: remove #include from misc.hh since not everyone needs it. --- src/arch/alpha/miscregfile.cc | 2 ++ src/arch/sparc/pagetable.hh | 2 ++ src/arch/x86/emulenv.cc | 2 ++ src/arch/x86/predecoder.hh | 2 ++ 4 files changed, 8 insertions(+) (limited to 'src/arch') diff --git a/src/arch/alpha/miscregfile.cc b/src/arch/alpha/miscregfile.cc index f119ca6bb..61a86f1fb 100644 --- a/src/arch/alpha/miscregfile.cc +++ b/src/arch/alpha/miscregfile.cc @@ -30,6 +30,8 @@ * Kevin Lim */ +#include + #include "arch/alpha/miscregfile.hh" #include "base/misc.hh" diff --git a/src/arch/sparc/pagetable.hh b/src/arch/sparc/pagetable.hh index d787f30e4..ee4ca0c2c 100644 --- a/src/arch/sparc/pagetable.hh +++ b/src/arch/sparc/pagetable.hh @@ -31,6 +31,8 @@ #ifndef __ARCH_SPARC_PAGETABLE_HH__ #define __ARCH_SPARC_PAGETABLE_HH__ +#include + #include "arch/sparc/isa_traits.hh" #include "base/bitfield.hh" #include "base/misc.hh" diff --git a/src/arch/x86/emulenv.cc b/src/arch/x86/emulenv.cc index 142e233db..30ed80942 100644 --- a/src/arch/x86/emulenv.cc +++ b/src/arch/x86/emulenv.cc @@ -55,6 +55,8 @@ * Authors: Gabe Black */ +#include + #include "arch/x86/emulenv.hh" #include "base/misc.hh" diff --git a/src/arch/x86/predecoder.hh b/src/arch/x86/predecoder.hh index 6e41e8134..a16ce6fb8 100644 --- a/src/arch/x86/predecoder.hh +++ b/src/arch/x86/predecoder.hh @@ -58,6 +58,8 @@ #ifndef __ARCH_X86_PREDECODER_HH__ #define __ARCH_X86_PREDECODER_HH__ +#include + #include "arch/x86/types.hh" #include "base/bitfield.hh" #include "base/misc.hh" -- cgit v1.2.3 From b03c95d075b74913313576e6e1fa4fc6b1f4dcb2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 10 Oct 2008 23:39:53 -0700 Subject: X86: Create SimObjects in python and C++ to represent the Intel MP tables. --- src/arch/x86/X86System.py | 7 + src/arch/x86/bios/IntelMP.py | 233 +++++++++++++++++++++ src/arch/x86/bios/SConscript | 4 + src/arch/x86/bios/intelmp.cc | 476 +++++++++++++++++++++++++++++++++++++++++++ src/arch/x86/bios/intelmp.hh | 330 ++++++++++++++++++++++++++++++ src/arch/x86/system.cc | 50 ++++- src/arch/x86/system.hh | 10 + 7 files changed, 1104 insertions(+), 6 deletions(-) create mode 100644 src/arch/x86/bios/IntelMP.py create mode 100644 src/arch/x86/bios/intelmp.cc create mode 100644 src/arch/x86/bios/intelmp.hh (limited to 'src/arch') diff --git a/src/arch/x86/X86System.py b/src/arch/x86/X86System.py index 5fe69c709..fc7a5acd0 100644 --- a/src/arch/x86/X86System.py +++ b/src/arch/x86/X86System.py @@ -56,12 +56,19 @@ from m5.params import * from E820 import X86E820Table, X86E820Entry from SMBios import X86SMBiosSMBiosTable +from IntelMP import X86IntelMPFloatingPointer, X86IntelMPConfigTable from System import System class X86System(System): type = 'X86System' smbios_table = Param.X86SMBiosSMBiosTable( X86SMBiosSMBiosTable(), 'table of smbios/dmi information') + intel_mp_pointer = Param.X86IntelMPFloatingPointer( + X86IntelMPFloatingPointer(), + 'intel mp spec floating pointer structure') + intel_mp_table = Param.X86IntelMPConfigTable( + X86IntelMPConfigTable(), + 'intel mp spec configuration table') class LinuxX86System(X86System): type = 'LinuxX86System' diff --git a/src/arch/x86/bios/IntelMP.py b/src/arch/x86/bios/IntelMP.py new file mode 100644 index 000000000..70e7963fa --- /dev/null +++ b/src/arch/x86/bios/IntelMP.py @@ -0,0 +1,233 @@ +# Copyright (c) 2008 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use of this software in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# +# The software must be used only for Non-Commercial Use which means any +# use which is NOT directed to receiving any direct monetary +# compensation for, or commercial advantage from such use. Illustrative +# examples of non-commercial use are academic research, personal study, +# teaching, education and corporate research & development. +# Illustrative examples of commercial use are distributing products for +# commercial advantage and providing services using the software for +# commercial advantage. +# +# If you wish to use this software or functionality therein that may be +# covered by patents for commercial use, please contact: +# Director of Intellectual Property Licensing +# Office of Strategy and Technology +# Hewlett-Packard Company +# 1501 Page Mill Road +# Palo Alto, California 94304 +# +# Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. Redistributions +# in binary form must reproduce the above copyright notice, this list of +# conditions and the following disclaimer in the documentation and/or +# other materials provided with the distribution. Neither the name of +# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. No right of +# sublicense is granted herewith. Derivatives of the software and +# output created using the software may be prepared, but only for +# Non-Commercial Uses. Derivatives of the software may be shared with +# others provided: (i) the others agree to abide by the list of +# conditions herein which includes the Non-Commercial Use restrictions; +# and (ii) such Derivatives of the software include the above copyright +# notice to acknowledge the contribution from this software where +# applicable, this list of conditions and the disclaimer below. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Gabe Black + +from m5.params import * +from m5.SimObject import SimObject + +class X86IntelMPFloatingPointer(SimObject): + type = 'X86IntelMPFloatingPointer' + cxx_class = 'X86ISA::IntelMP::FloatingPointer' + + # The minor revision of the spec to support. The major version is assumed + # to be 1 in accordance with the spec. + spec_rev = Param.UInt8(4, 'minor revision of the MP spec supported') + # If no default configuration is used, set this to 0. + default_config = Param.UInt8(0, 'which default configuration to use') + imcr_present = Param.Bool(True, + 'whether the IMCR register is present in the APIC') + +class X86IntelMPConfigTable(SimObject): + type = 'X86IntelMPConfigTable' + cxx_class = 'X86ISA::IntelMP::ConfigTable' + + spec_rev = Param.UInt8(4, 'minor revision of the MP spec supported') + oem_id = Param.String("", 'system manufacturer') + product_id = Param.String("", 'product family') + oem_table_addr = Param.UInt32(0, + 'pointer to the optional oem configuration table') + oem_table_size = Param.UInt16(0, 'size of the oem configuration table') + local_apic = Param.UInt32(0xFEE00000, 'address of the local APIC') + + base_entries = VectorParam.X86IntelMPBaseConfigEntry([], + 'base configuration table entries') + + ext_entries = VectorParam.X86IntelMPExtConfigEntry([], + 'extended configuration table entries') + +class X86IntelMPBaseConfigEntry(SimObject): + type = 'X86IntelMPBaseConfigEntry' + cxx_class = 'X86ISA::IntelMP::BaseConfigEntry' + abstract = True + +class X86IntelMPExtConfigEntry(SimObject): + type = 'X86IntelMPExtConfigEntry' + cxx_class = 'X86ISA::IntelMP::ExtConfigEntry' + abstract = True + +class X86IntelMPProcessor(X86IntelMPBaseConfigEntry): + type = 'X86IntelMPProcessor' + cxx_class = 'X86ISA::IntelMP::Processor' + + local_apic_id = Param.UInt8(0, 'local APIC id') + local_apic_version = Param.UInt8(0, + 'bits 0-7 of the local APIC version register') + enable = Param.Bool(True, 'if this processor is usable') + bootstrap = Param.Bool(False, 'if this is the bootstrap processor') + + stepping = Param.UInt8(0) + model = Param.UInt8(0) + family = Param.UInt8(0) + + feature_flags = Param.UInt32(0, 'flags returned by the CPUID instruction') + +class X86IntelMPBus(X86IntelMPBaseConfigEntry): + type = 'X86IntelMPBus' + cxx_class = 'X86ISA::IntelMP::Bus' + + bus_id = Param.UInt8(0, 'bus id assigned by the bios') + bus_type = Param.String("", 'string that identify the bus type') + # Legal values for bus_type are: + # + # "CBUS", "CBUSII", "EISA", "FUTURE", "INTERN", "ISA", "MBI", "MBII", + # "MCA", "MPI", "MPSA", "NUBUS", "PCI", "PCMCIA", "TC", "VL", "VME", + # "XPRESS" + +class X86IntelMPIOAPIC(X86IntelMPBaseConfigEntry): + type = 'X86IntelMPIOAPIC' + cxx_class = 'X86ISA::IntelMP::IOAPIC' + + id = Param.UInt8(0, 'id of this APIC') + version = Param.UInt8(0, 'bits 0-7 of the version register') + + enable = Param.Bool(True, 'if this APIC is usable') + + address = Param.UInt32(0xfec00000, 'address of this APIC') + +class X86IntelMPInterruptType(Enum): + map = {'INT' : 0, + 'NMI' : 1, + 'SMI' : 2, + 'ExtInt' : 3 + } + +class X86IntelMPPolarity(Enum): + map = {'ConformPolarity' : 0, + 'ActiveHigh' : 1, + 'ActiveLow' : 3 + } + +class X86IntelMPTriggerMode(Enum): + map = {'ConformTrigger' : 0, + 'EdgeTrigger' : 1, + 'LevelTrigger' : 3 + } + +class X86IntelMPIOIntAssignment(X86IntelMPBaseConfigEntry): + type = 'X86IntelMPIOIntAssignment' + cxx_class = 'X86ISA::IntelMP::IOIntAssignment' + + interrupt_type = Param.X86IntelMPInterruptType('INT', 'type of interrupt') + + polarity = Param.X86IntelMPPolarity('ConformPolarity', 'polarity') + trigger = Param.X86IntelMPTriggerMode('ConformTrigger', 'trigger mode') + + source_bus_id = Param.UInt8(0, + 'id of the bus from which the interrupt signal comes') + source_bus_irq = Param.UInt8(0, + 'which interrupt signal from the source bus') + + dest_io_apic_id = Param.UInt8(0, + 'id of the IO APIC the interrupt is going to') + dest_io_apic_intin = Param.UInt8(0, + 'the INTIN pin on the IO APIC the interrupt is connected to') + +class X86IntelMPLocalIntAssignment(X86IntelMPBaseConfigEntry): + type = 'X86IntelMPLocalIntAssignment' + cxx_class = 'X86ISA::IntelMP::LocalIntAssignment' + + interrupt_type = Param.X86IntelMPInterruptType('INT', 'type of interrupt') + + polarity = Param.X86IntelMPPolarity('ConformPolarity', 'polarity') + trigger = Param.X86IntelMPTriggerMode('ConformTrigger', 'trigger mode') + + source_bus_id = Param.UInt8(0, + 'id of the bus from which the interrupt signal comes') + source_bus_irq = Param.UInt8(0, + 'which interrupt signal from the source bus') + + dest_local_apic_id = Param.UInt8(0, + 'id of the local APIC the interrupt is going to') + dest_local_apic_intin = Param.UInt8(0, + 'the INTIN pin on the local APIC the interrupt is connected to') + +class X86IntelMPAddressType(Enum): + map = {"IOAddress" : 0, + "MemoryAddress" : 1, + "PrefetchAddress" : 2 + } + +class X86IntelMPAddrSpaceMapping(X86IntelMPExtConfigEntry): + type = 'X86IntelMPAddrSpaceMapping' + cxx_class = 'X86ISA::IntelMP::AddrSpaceMapping' + + bus_id = Param.UInt8(0, 'id of the bus the address space is mapped to') + address_type = Param.X86IntelMPAddressType('IOAddress', + 'address type used to access bus') + address = Param.Addr(0, 'starting address of the mapping') + length = Param.UInt64(0, 'length of mapping in bytes') + +class X86IntelMPBusHierarchy(X86IntelMPExtConfigEntry): + type = 'X86IntelMPBusHierarchy' + cxx_class = 'X86ISA::IntelMP::BusHierarchy' + + bus_id = Param.UInt8(0, 'id of the bus being described') + subtractive_decode = Param.Bool(False, + 'whether this bus contains all addresses not used by its children') + parent_bus = Param.UInt8(0, 'bus id of this busses parent') + +class X86IntelMPRangeList(Enum): + map = {"ISACompatible" : 0, + "VGACompatible" : 1 + } + +class X86IntelMPCompatAddrSpaceMod(X86IntelMPExtConfigEntry): + type = 'X86IntelMPCompatAddrSpaceMod' + cxx_class = 'X86ISA::IntelMP::CompatAddrSpaceMod' + + bus_id = Param.UInt8(0, 'id of the bus being described') + add = Param.Bool(False, + 'if the range should be added to the original mapping') + range_list = Param.X86IntelMPRangeList('ISACompatible', + 'which predefined range of addresses to use') diff --git a/src/arch/x86/bios/SConscript b/src/arch/x86/bios/SConscript index cdb5f390f..c4f4f80e6 100644 --- a/src/arch/x86/bios/SConscript +++ b/src/arch/x86/bios/SConscript @@ -67,3 +67,7 @@ if env['TARGET_ISA'] == 'x86': # The DMI tables. SimObject('SMBios.py') Source('smbios.cc') + + # Intel Multiprocessor Specification Configuration Table + SimObject('IntelMP.py') + Source('intelmp.cc') diff --git a/src/arch/x86/bios/intelmp.cc b/src/arch/x86/bios/intelmp.cc new file mode 100644 index 000000000..2332e7a5c --- /dev/null +++ b/src/arch/x86/bios/intelmp.cc @@ -0,0 +1,476 @@ +/* + * Copyright (c) 2008 The Hewlett-Packard Development Company + * All rights reserved. + * + * Redistribution and use of this software in source and binary forms, + * with or without modification, are permitted provided that the + * following conditions are met: + * + * The software must be used only for Non-Commercial Use which means any + * use which is NOT directed to receiving any direct monetary + * compensation for, or commercial advantage from such use. Illustrative + * examples of non-commercial use are academic research, personal study, + * teaching, education and corporate research & development. + * Illustrative examples of commercial use are distributing products for + * commercial advantage and providing services using the software for + * commercial advantage. + * + * If you wish to use this software or functionality therein that may be + * covered by patents for commercial use, please contact: + * Director of Intellectual Property Licensing + * Office of Strategy and Technology + * Hewlett-Packard Company + * 1501 Page Mill Road + * Palo Alto, California 94304 + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. Redistributions + * in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. Neither the name of + * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. No right of + * sublicense is granted herewith. Derivatives of the software and + * output created using the software may be prepared, but only for + * Non-Commercial Uses. Derivatives of the software may be shared with + * others provided: (i) the others agree to abide by the list of + * conditions herein which includes the Non-Commercial Use restrictions; + * and (ii) such Derivatives of the software include the above copyright + * notice to acknowledge the contribution from this software where + * applicable, this list of conditions and the disclaimer below. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#include "arch/x86/bios/intelmp.hh" +#include "arch/x86/isa_traits.hh" +#include "base/misc.hh" +#include "mem/port.hh" +#include "sim/byteswap.hh" +#include "sim/host.hh" + +// Config entry types +#include "params/X86IntelMPBaseConfigEntry.hh" +#include "params/X86IntelMPExtConfigEntry.hh" + +// General table structures +#include "params/X86IntelMPConfigTable.hh" +#include "params/X86IntelMPFloatingPointer.hh" + +// Base entry types +#include "params/X86IntelMPBus.hh" +#include "params/X86IntelMPIOAPIC.hh" +#include "params/X86IntelMPIOIntAssignment.hh" +#include "params/X86IntelMPLocalIntAssignment.hh" +#include "params/X86IntelMPProcessor.hh" + +// Extended entry types +#include "params/X86IntelMPAddrSpaceMapping.hh" +#include "params/X86IntelMPBusHierarchy.hh" +#include "params/X86IntelMPCompatAddrSpaceMod.hh" + +using namespace std; + +const char X86ISA::IntelMP::FloatingPointer::signature[] = "_MP_"; + +template +uint8_t +writeOutField(FunctionalPort * port, Addr addr, T val) +{ + T guestVal = X86ISA::htog(val); + port->writeBlob(addr, (uint8_t *)(&guestVal), sizeof(T)); + + uint8_t checkSum = 0; + while(guestVal) { + checkSum += guestVal; + guestVal >>= 8; + } + return checkSum; +} + +uint8_t +writeOutString(FunctionalPort * port, Addr addr, string str, int length) +{ + char cleanedString[length + 1]; + cleanedString[length] = 0; + + if (str.length() > length) { + memcpy(cleanedString, str.c_str(), length); + warn("Intel MP configuration table string \"%s\" " + "will be truncated to \"%s\".\n", str, cleanedString); + } else { + memcpy(cleanedString, str.c_str(), str.length()); + memset(cleanedString + str.length(), 0, length - str.length()); + } + port->writeBlob(addr, (uint8_t *)(&cleanedString), length); + + uint8_t checkSum = 0; + for (int i = 0; i < length; i++) + checkSum += cleanedString[i]; + + return checkSum; +} + +Addr +X86ISA::IntelMP::FloatingPointer::writeOut(FunctionalPort * port, Addr addr) +{ + // Make sure that either a config table is present or a default + // configuration was found but not both. + if (!tableAddr && !defaultConfig) + fatal("Either an MP configuration table or a default configuration " + "must be used."); + if (tableAddr && defaultConfig) + fatal("Both an MP configuration table and a default configuration " + "were set."); + + uint8_t checkSum = 0; + + port->writeBlob(addr, (uint8_t *)signature, 4); + for (int i = 0; i < 4; i++) + checkSum += signature[i]; + + checkSum += writeOutField(port, addr + 4, tableAddr); + + // The length of the structure in paragraphs, aka 16 byte chunks. + uint8_t length = 1; + port->writeBlob(addr + 8, &length, 1); + checkSum += length; + + port->writeBlob(addr + 9, &specRev, 1); + checkSum += specRev; + + port->writeBlob(addr + 11, &defaultConfig, 1); + checkSum += defaultConfig; + + uint32_t features2_5 = imcrPresent ? (1 << 7) : 0; + checkSum += writeOutField(port, addr + 12, features2_5); + + checkSum = -checkSum; + port->writeBlob(addr + 10, &checkSum, 1); + + return 16; +} + +X86ISA::IntelMP::FloatingPointer::FloatingPointer(Params * p) : + SimObject(p), tableAddr(0), specRev(p->spec_rev), + defaultConfig(p->default_config), imcrPresent(p->imcr_present) +{} + +X86ISA::IntelMP::FloatingPointer * +X86IntelMPFloatingPointerParams::create() +{ + return new X86ISA::IntelMP::FloatingPointer(this); +} + +Addr +X86ISA::IntelMP::BaseConfigEntry::writeOut(FunctionalPort * port, + Addr addr, uint8_t &checkSum) +{ + port->writeBlob(addr, &type, 1); + checkSum += type; + return 1; +} + +X86ISA::IntelMP::BaseConfigEntry::BaseConfigEntry(Params * p, uint8_t _type) : + SimObject(p), type(_type) +{} + +Addr +X86ISA::IntelMP::ExtConfigEntry::writeOut(FunctionalPort * port, + Addr addr, uint8_t &checkSum) +{ + port->writeBlob(addr, &type, 1); + checkSum += type; + port->writeBlob(addr + 1, &length, 1); + checkSum += length; + return 1; +} + +X86ISA::IntelMP::ExtConfigEntry::ExtConfigEntry(Params * p, + uint8_t _type, uint8_t _length) : + SimObject(p), type(_type), length(_length) +{} + +const char X86ISA::IntelMP::ConfigTable::signature[] = "PCMP"; + +Addr +X86ISA::IntelMP::ConfigTable::writeOut(FunctionalPort * port, Addr addr) +{ + uint8_t checkSum = 0; + + port->writeBlob(addr, (uint8_t *)signature, 4); + for (int i = 0; i < 4; i++) + checkSum += signature[i]; + + // Base table length goes here but will be calculated later. + + port->writeBlob(addr + 6, (uint8_t *)(&specRev), 1); + checkSum += specRev; + + // The checksum goes here but is still being calculated. + + checkSum += writeOutString(port, addr + 8, oemID, 8); + checkSum += writeOutString(port, addr + 16, productID, 12); + + checkSum += writeOutField(port, addr + 28, oemTableAddr); + checkSum += writeOutField(port, addr + 32, oemTableSize); + checkSum += writeOutField(port, addr + 34, (uint16_t)baseEntries.size()); + checkSum += writeOutField(port, addr + 36, localApic); + + uint8_t reserved = 0; + port->writeBlob(addr + 43, &reserved, 1); + checkSum += reserved; + + vector::iterator baseEnt; + uint16_t offset = 44; + for (baseEnt = baseEntries.begin(); + baseEnt != baseEntries.end(); baseEnt++) { + offset += (*baseEnt)->writeOut(port, addr + offset, checkSum); + } + + // We've found the end of the base table this point. + checkSum += writeOutField(port, addr + 4, offset); + + vector::iterator extEnt; + uint16_t extOffset = 0; + uint8_t extCheckSum = 0; + for (extEnt = extEntries.begin(); + extEnt != extEntries.end(); extEnt++) { + extOffset += (*extEnt)->writeOut(port, + addr + offset + extOffset, extCheckSum); + } + + checkSum += writeOutField(port, addr + 40, extOffset); + extCheckSum = -extCheckSum; + checkSum += writeOutField(port, addr + 42, extCheckSum); + + // And now, we finally have the whole check sum completed. + checkSum = -checkSum; + writeOutField(port, addr + 7, checkSum); + + return offset + extOffset; +}; + +X86ISA::IntelMP::ConfigTable::ConfigTable(Params * p) : SimObject(p), + specRev(p->spec_rev), oemID(p->oem_id), productID(p->product_id), + oemTableAddr(p->oem_table_addr), oemTableSize(p->oem_table_size), + localApic(p->local_apic), + baseEntries(p->base_entries), extEntries(p->ext_entries) +{} + +X86ISA::IntelMP::ConfigTable * +X86IntelMPConfigTableParams::create() +{ + return new X86ISA::IntelMP::ConfigTable(this); +} + +Addr +X86ISA::IntelMP::Processor::writeOut( + FunctionalPort * port, Addr addr, uint8_t &checkSum) +{ + BaseConfigEntry::writeOut(port, addr, checkSum); + checkSum += writeOutField(port, addr + 1, localApicID); + checkSum += writeOutField(port, addr + 2, localApicVersion); + checkSum += writeOutField(port, addr + 3, cpuFlags); + checkSum += writeOutField(port, addr + 4, cpuSignature); + checkSum += writeOutField(port, addr + 8, featureFlags); + + uint32_t reserved = 0; + port->writeBlob(addr + 12, (uint8_t *)(&reserved), 4); + port->writeBlob(addr + 16, (uint8_t *)(&reserved), 4); + return 20; +} + +X86ISA::IntelMP::Processor::Processor(Params * p) : BaseConfigEntry(p, 0), + localApicID(p->local_apic_id), localApicVersion(p->local_apic_version), + cpuFlags(0), cpuSignature(0), featureFlags(p->feature_flags) +{ + if (p->enable) + cpuFlags |= (1 << 0); + if (p->bootstrap) + cpuFlags |= (1 << 1); + + replaceBits(cpuSignature, 0, 3, p->stepping); + replaceBits(cpuSignature, 4, 7, p->model); + replaceBits(cpuSignature, 8, 11, p->family); +} + +X86ISA::IntelMP::Processor * +X86IntelMPProcessorParams::create() +{ + return new X86ISA::IntelMP::Processor(this); +} + +Addr +X86ISA::IntelMP::Bus::writeOut( + FunctionalPort * port, Addr addr, uint8_t &checkSum) +{ + BaseConfigEntry::writeOut(port, addr, checkSum); + checkSum += writeOutField(port, addr + 1, busID); + checkSum += writeOutString(port, addr + 2, busType, 6); + return 8; +} + +X86ISA::IntelMP::Bus::Bus(Params * p) : BaseConfigEntry(p, 1), + busID(p->bus_id), busType(p->bus_type) +{} + +X86ISA::IntelMP::Bus * +X86IntelMPBusParams::create() +{ + return new X86ISA::IntelMP::Bus(this); +} + +Addr +X86ISA::IntelMP::IOAPIC::writeOut( + FunctionalPort * port, Addr addr, uint8_t &checkSum) +{ + BaseConfigEntry::writeOut(port, addr, checkSum); + checkSum += writeOutField(port, addr + 1, id); + checkSum += writeOutField(port, addr + 2, version); + checkSum += writeOutField(port, addr + 3, flags); + checkSum += writeOutField(port, addr + 4, address); + return 8; +} + +X86ISA::IntelMP::IOAPIC::IOAPIC(Params * p) : BaseConfigEntry(p, 2), + id(p->id), version(p->version), flags(0), address(p->address) +{ + if (p->enable) + flags |= 1; +} + +X86ISA::IntelMP::IOAPIC * +X86IntelMPIOAPICParams::create() +{ + return new X86ISA::IntelMP::IOAPIC(this); +} + +Addr +X86ISA::IntelMP::IntAssignment::writeOut( + FunctionalPort * port, Addr addr, uint8_t &checkSum) +{ + BaseConfigEntry::writeOut(port, addr, checkSum); + checkSum += writeOutField(port, addr + 1, interruptType); + checkSum += writeOutField(port, addr + 2, flags); + checkSum += writeOutField(port, addr + 4, sourceBusID); + checkSum += writeOutField(port, addr + 5, sourceBusIRQ); + checkSum += writeOutField(port, addr + 6, destApicID); + checkSum += writeOutField(port, addr + 7, destApicIntIn); + return 8; +} + +X86ISA::IntelMP::IOIntAssignment::IOIntAssignment(Params * p) : + IntAssignment(p, p->interrupt_type, p->polarity, p->trigger, 3, + p->source_bus_id, p->source_bus_irq, + p->dest_io_apic_id, p->dest_io_apic_intin) +{} + +X86ISA::IntelMP::IOIntAssignment * +X86IntelMPIOIntAssignmentParams::create() +{ + return new X86ISA::IntelMP::IOIntAssignment(this); +} + +X86ISA::IntelMP::LocalIntAssignment::LocalIntAssignment(Params * p) : + IntAssignment(p, p->interrupt_type, p->polarity, p->trigger, 4, + p->source_bus_id, p->source_bus_irq, + p->dest_local_apic_id, p->dest_local_apic_intin) +{} + +X86ISA::IntelMP::LocalIntAssignment * +X86IntelMPLocalIntAssignmentParams::create() +{ + return new X86ISA::IntelMP::LocalIntAssignment(this); +} + +Addr +X86ISA::IntelMP::AddrSpaceMapping::writeOut( + FunctionalPort * port, Addr addr, uint8_t &checkSum) +{ + ExtConfigEntry::writeOut(port, addr, checkSum); + checkSum += writeOutField(port, addr + 2, busID); + checkSum += writeOutField(port, addr + 3, addrType); + checkSum += writeOutField(port, addr + 4, addr); + checkSum += writeOutField(port, addr + 12, addrLength); + return length; +} + +X86ISA::IntelMP::AddrSpaceMapping::AddrSpaceMapping(Params * p) : + ExtConfigEntry(p, 128, 20), + busID(p->bus_id), addrType(p->address_type), + addr(p->address), addrLength(p->length) +{} + +X86ISA::IntelMP::AddrSpaceMapping * +X86IntelMPAddrSpaceMappingParams::create() +{ + return new X86ISA::IntelMP::AddrSpaceMapping(this); +} + +Addr +X86ISA::IntelMP::BusHierarchy::writeOut( + FunctionalPort * port, Addr addr, uint8_t &checkSum) +{ + ExtConfigEntry::writeOut(port, addr, checkSum); + checkSum += writeOutField(port, addr + 2, busID); + checkSum += writeOutField(port, addr + 3, info); + checkSum += writeOutField(port, addr + 4, parentBus); + + uint32_t reserved = 0; + port->writeBlob(addr + 5, (uint8_t *)(&reserved), 3); + + return length; +} + +X86ISA::IntelMP::BusHierarchy::BusHierarchy(Params * p) : + ExtConfigEntry(p, 129, 8), + busID(p->bus_id), info(0), parentBus(p->parent_bus) +{ + if (p->subtractive_decode) + info |= 1; +} + +X86ISA::IntelMP::BusHierarchy * +X86IntelMPBusHierarchyParams::create() +{ + return new X86ISA::IntelMP::BusHierarchy(this); +} + +Addr +X86ISA::IntelMP::CompatAddrSpaceMod::writeOut( + FunctionalPort * port, Addr addr, uint8_t &checkSum) +{ + ExtConfigEntry::writeOut(port, addr, checkSum); + checkSum += writeOutField(port, addr + 2, busID); + checkSum += writeOutField(port, addr + 3, mod); + checkSum += writeOutField(port, addr + 4, rangeList); + return length; +} + +X86ISA::IntelMP::CompatAddrSpaceMod::CompatAddrSpaceMod(Params * p) : + ExtConfigEntry(p, 130, 8), + busID(p->bus_id), mod(0), rangeList(p->range_list) +{ + if (p->add) + mod |= 1; +} + +X86ISA::IntelMP::CompatAddrSpaceMod * +X86IntelMPCompatAddrSpaceModParams::create() +{ + return new X86ISA::IntelMP::CompatAddrSpaceMod(this); +} diff --git a/src/arch/x86/bios/intelmp.hh b/src/arch/x86/bios/intelmp.hh new file mode 100644 index 000000000..e8d1d656e --- /dev/null +++ b/src/arch/x86/bios/intelmp.hh @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2008 The Hewlett-Packard Development Company + * All rights reserved. + * + * Redistribution and use of this software in source and binary forms, + * with or without modification, are permitted provided that the + * following conditions are met: + * + * The software must be used only for Non-Commercial Use which means any + * use which is NOT directed to receiving any direct monetary + * compensation for, or commercial advantage from such use. Illustrative + * examples of non-commercial use are academic research, personal study, + * teaching, education and corporate research & development. + * Illustrative examples of commercial use are distributing products for + * commercial advantage and providing services using the software for + * commercial advantage. + * + * If you wish to use this software or functionality therein that may be + * covered by patents for commercial use, please contact: + * Director of Intellectual Property Licensing + * Office of Strategy and Technology + * Hewlett-Packard Company + * 1501 Page Mill Road + * Palo Alto, California 94304 + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. Redistributions + * in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. Neither the name of + * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. No right of + * sublicense is granted herewith. Derivatives of the software and + * output created using the software may be prepared, but only for + * Non-Commercial Uses. Derivatives of the software may be shared with + * others provided: (i) the others agree to abide by the list of + * conditions herein which includes the Non-Commercial Use restrictions; + * and (ii) such Derivatives of the software include the above copyright + * notice to acknowledge the contribution from this software where + * applicable, this list of conditions and the disclaimer below. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef __ARCH_X86_BIOS_INTELMP_HH__ +#define __ARCH_X86_BIOS_INTELMP_HH__ + +#include +#include + +#include "base/bitfield.hh" +#include "sim/sim_object.hh" + +#include "enums/X86IntelMPAddressType.hh" +#include "enums/X86IntelMPInterruptType.hh" +#include "enums/X86IntelMPPolarity.hh" +#include "enums/X86IntelMPRangeList.hh" +#include "enums/X86IntelMPTriggerMode.hh" + +class FunctionalPort; + +// Config entry types +class X86IntelMPBaseConfigEntryParams; +class X86IntelMPExtConfigEntryParams; + +// General table structures +class X86IntelMPConfigTableParams; +class X86IntelMPFloatingPointerParams; + +// Base entry types +class X86IntelMPBusParams; +class X86IntelMPIOAPICParams; +class X86IntelMPIOIntAssignmentParams; +class X86IntelMPLocalIntAssignmentParams; +class X86IntelMPProcessorParams; + +// Extended entry types +class X86IntelMPAddrSpaceMappingParams; +class X86IntelMPBusHierarchyParams; +class X86IntelMPCompatAddrSpaceModParams; + +namespace X86ISA +{ + +namespace IntelMP +{ + +class FloatingPointer : public SimObject +{ + protected: + typedef X86IntelMPFloatingPointerParams Params; + + uint32_t tableAddr; + uint8_t specRev; + uint8_t defaultConfig; + bool imcrPresent; + + static const char signature[]; + + public: + + Addr writeOut(FunctionalPort * port, Addr addr); + + Addr getTableAddr() + { + return tableAddr; + } + + void setTableAddr(Addr addr) + { + tableAddr = addr; + } + + FloatingPointer(Params * p); +}; + +class BaseConfigEntry : public SimObject +{ + protected: + typedef X86IntelMPBaseConfigEntryParams Params; + + uint8_t type; + + public: + + virtual Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum); + + BaseConfigEntry(Params * p, uint8_t _type); +}; + +class ExtConfigEntry : public SimObject +{ + protected: + typedef X86IntelMPExtConfigEntryParams Params; + + uint8_t type; + uint8_t length; + + public: + + virtual Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum); + + ExtConfigEntry(Params * p, uint8_t _type, uint8_t _length); +}; + +class ConfigTable : public SimObject +{ + protected: + typedef X86IntelMPConfigTableParams Params; + + static const char signature[]; + + uint8_t specRev; + std::string oemID; + std::string productID; + uint32_t oemTableAddr; + uint16_t oemTableSize; + uint32_t localApic; + + std::vector baseEntries; + std::vector extEntries; + + public: + Addr writeOut(FunctionalPort * port, Addr addr); + + ConfigTable(Params * p); +}; + +class Processor : public BaseConfigEntry +{ + protected: + typedef X86IntelMPProcessorParams Params; + + uint8_t localApicID; + uint8_t localApicVersion; + uint8_t cpuFlags; + uint32_t cpuSignature; + uint32_t featureFlags; + + public: + Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum); + + Processor(Params * p); +}; + +class Bus : public BaseConfigEntry +{ + protected: + typedef X86IntelMPBusParams Params; + + uint8_t busID; + std::string busType; + + public: + Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum); + + Bus(Params * p); +}; + +class IOAPIC : public BaseConfigEntry +{ + protected: + typedef X86IntelMPIOAPICParams Params; + + uint8_t id; + uint8_t version; + uint8_t flags; + uint32_t address; + + public: + Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum); + + IOAPIC(Params * p); +}; + +class IntAssignment : public BaseConfigEntry +{ + protected: + uint8_t interruptType; + + uint16_t flags; + + uint8_t sourceBusID; + uint8_t sourceBusIRQ; + + uint8_t destApicID; + uint8_t destApicIntIn; + + public: + Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum); + + IntAssignment(X86IntelMPBaseConfigEntryParams * p, + Enums::X86IntelMPInterruptType _interruptType, + Enums::X86IntelMPPolarity polarity, + Enums::X86IntelMPTriggerMode trigger, + uint8_t _type, + uint8_t _sourceBusID, uint8_t _sourceBusIRQ, + uint8_t _destApicID, uint8_t _destApicIntIn) : + BaseConfigEntry(p, _type), + interruptType(_interruptType), flags(0), + sourceBusID(_sourceBusID), sourceBusIRQ(_sourceBusIRQ), + destApicID(_destApicID), destApicIntIn(_destApicIntIn) + { + replaceBits(flags, 0, 1, polarity); + replaceBits(flags, 2, 3, trigger); + } +}; + +class IOIntAssignment : public IntAssignment +{ + protected: + typedef X86IntelMPIOIntAssignmentParams Params; + + public: + IOIntAssignment(Params * p); +}; + +class LocalIntAssignment : public IntAssignment +{ + protected: + typedef X86IntelMPLocalIntAssignmentParams Params; + + public: + LocalIntAssignment(Params * p); +}; + +class AddrSpaceMapping : public ExtConfigEntry +{ + protected: + typedef X86IntelMPAddrSpaceMappingParams Params; + + uint8_t busID; + uint8_t addrType; + uint64_t addr; + uint64_t addrLength; + + public: + Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum); + + AddrSpaceMapping(Params * p); +}; + +class BusHierarchy : public ExtConfigEntry +{ + protected: + typedef X86IntelMPBusHierarchyParams Params; + + uint8_t busID; + uint8_t info; + uint8_t parentBus; + + public: + Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum); + + BusHierarchy(Params * p); +}; + +class CompatAddrSpaceMod : public ExtConfigEntry +{ + protected: + typedef X86IntelMPCompatAddrSpaceModParams Params; + + uint8_t busID; + uint8_t mod; + uint32_t rangeList; + + public: + Addr writeOut(FunctionalPort * port, Addr addr, uint8_t &checkSum); + + CompatAddrSpaceMod(Params * p); +}; + +} //IntelMP + +} //X86ISA + +#endif diff --git a/src/arch/x86/system.cc b/src/arch/x86/system.cc index 9006ce227..b2fadd682 100644 --- a/src/arch/x86/system.cc +++ b/src/arch/x86/system.cc @@ -56,12 +56,14 @@ */ #include "arch/x86/bios/smbios.hh" +#include "arch/x86/bios/intelmp.hh" #include "arch/x86/miscregs.hh" #include "arch/x86/system.hh" #include "arch/vtophys.hh" -#include "base/remote_gdb.hh" +#include "base/intmath.hh" #include "base/loader/object_file.hh" #include "base/loader/symtab.hh" +#include "base/remote_gdb.hh" #include "base/trace.hh" #include "cpu/thread_context.hh" #include "mem/physical.hh" @@ -72,8 +74,10 @@ using namespace LittleEndianGuest; using namespace X86ISA; -X86System::X86System(Params *p) - : System(p), smbiosTable(p->smbios_table) +X86System::X86System(Params *p) : + System(p), smbiosTable(p->smbios_table), + mpFloatingPointer(p->intel_mp_pointer), + mpConfigTable(p->intel_mp_table) {} void @@ -232,11 +236,16 @@ X86System::startup() // We should now be in long mode. Yay! Addr ebdaPos = 0xF0000; + Addr fixed, table; - Addr headerSize, structSize; //Write out the SMBios/DMI table - writeOutSMBiosTable(ebdaPos, headerSize, structSize); - ebdaPos += (headerSize + structSize); + writeOutSMBiosTable(ebdaPos, fixed, table); + ebdaPos += (fixed + table); + ebdaPos = roundUp(ebdaPos, 16); + + //Write out the Intel MP Specification configuration table + writeOutMPTable(ebdaPos, fixed, table); + ebdaPos += (fixed + table); } void @@ -260,6 +269,35 @@ X86System::writeOutSMBiosTable(Addr header, assert(table > header || table + structSize <= header); } +void +X86System::writeOutMPTable(Addr fp, + Addr &fpSize, Addr &tableSize, Addr table) +{ + // Get a port to write the table and header to memory. + FunctionalPort * physPort = threadContexts[0]->getPhysPort(); + + // If the table location isn't specified and it exists, just put + // it after the floating pointer. The fp size as of the 1.4 Intel MP + // specification is 0x10 bytes. + if (mpConfigTable) { + if (!table) + table = fp + 0x10; + mpFloatingPointer->setTableAddr(table); + } + + fpSize = mpFloatingPointer->writeOut(physPort, fp); + if (mpConfigTable) + tableSize = mpConfigTable->writeOut(physPort, table); + else + tableSize = 0; + + // Do some bounds checking to make sure we at least didn't step on + // ourselves and the fp structure was the size we thought it was. + assert(fp > table || fp + fpSize <= table); + assert(table > fp || table + tableSize <= fp); + assert(fpSize == 0x10); +} + X86System::~X86System() { diff --git a/src/arch/x86/system.hh b/src/arch/x86/system.hh index 2120bc090..7433cc644 100644 --- a/src/arch/x86/system.hh +++ b/src/arch/x86/system.hh @@ -74,6 +74,11 @@ namespace X86ISA { class SMBiosTable; } + namespace IntelMP + { + class FloatingPointer; + class ConfigTable; + } } class X86System : public System @@ -95,10 +100,15 @@ class X86System : public System protected: X86ISA::SMBios::SMBiosTable * smbiosTable; + X86ISA::IntelMP::FloatingPointer * mpFloatingPointer; + X86ISA::IntelMP::ConfigTable * mpConfigTable; void writeOutSMBiosTable(Addr header, Addr &headerSize, Addr &tableSize, Addr table = 0); + void writeOutMPTable(Addr fp, + Addr &fpSize, Addr &tableSize, Addr table = 0); + const Params *params() const { return (const Params *)_params; } virtual Addr fixFuncEventAddr(Addr addr) -- cgit v1.2.3 From 3d1734ec29a0572a2c0fe403d737adbd9756c993 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 10 Oct 2008 23:43:33 -0700 Subject: X86: Create SimObjects in python and C++ to represent the ACPI system description tables. --- src/arch/x86/X86System.py | 3 + src/arch/x86/bios/ACPI.py | 99 +++++++++++++++++++++++++++++ src/arch/x86/bios/SConscript | 4 ++ src/arch/x86/bios/acpi.cc | 109 ++++++++++++++++++++++++++++++++ src/arch/x86/bios/acpi.hh | 147 +++++++++++++++++++++++++++++++++++++++++++ src/arch/x86/system.cc | 3 +- src/arch/x86/system.hh | 1 + 7 files changed, 365 insertions(+), 1 deletion(-) create mode 100644 src/arch/x86/bios/ACPI.py create mode 100644 src/arch/x86/bios/acpi.cc create mode 100644 src/arch/x86/bios/acpi.hh (limited to 'src/arch') diff --git a/src/arch/x86/X86System.py b/src/arch/x86/X86System.py index fc7a5acd0..527831205 100644 --- a/src/arch/x86/X86System.py +++ b/src/arch/x86/X86System.py @@ -57,6 +57,7 @@ from m5.params import * from E820 import X86E820Table, X86E820Entry from SMBios import X86SMBiosSMBiosTable from IntelMP import X86IntelMPFloatingPointer, X86IntelMPConfigTable +from ACPI import X86ACPIRSDP from System import System class X86System(System): @@ -69,6 +70,8 @@ class X86System(System): intel_mp_table = Param.X86IntelMPConfigTable( X86IntelMPConfigTable(), 'intel mp spec configuration table') + acpi_description_table_pointer = Param.X86ACPIRSDP( + X86ACPIRSDP(), 'ACPI root description pointer structure') class LinuxX86System(X86System): type = 'LinuxX86System' diff --git a/src/arch/x86/bios/ACPI.py b/src/arch/x86/bios/ACPI.py new file mode 100644 index 000000000..20eb66be0 --- /dev/null +++ b/src/arch/x86/bios/ACPI.py @@ -0,0 +1,99 @@ +# Copyright (c) 2008 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use of this software in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# +# The software must be used only for Non-Commercial Use which means any +# use which is NOT directed to receiving any direct monetary +# compensation for, or commercial advantage from such use. Illustrative +# examples of non-commercial use are academic research, personal study, +# teaching, education and corporate research & development. +# Illustrative examples of commercial use are distributing products for +# commercial advantage and providing services using the software for +# commercial advantage. +# +# If you wish to use this software or functionality therein that may be +# covered by patents for commercial use, please contact: +# Director of Intellectual Property Licensing +# Office of Strategy and Technology +# Hewlett-Packard Company +# 1501 Page Mill Road +# Palo Alto, California 94304 +# +# Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. Redistributions +# in binary form must reproduce the above copyright notice, this list of +# conditions and the following disclaimer in the documentation and/or +# other materials provided with the distribution. Neither the name of +# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. No right of +# sublicense is granted herewith. Derivatives of the software and +# output created using the software may be prepared, but only for +# Non-Commercial Uses. Derivatives of the software may be shared with +# others provided: (i) the others agree to abide by the list of +# conditions herein which includes the Non-Commercial Use restrictions; +# and (ii) such Derivatives of the software include the above copyright +# notice to acknowledge the contribution from this software where +# applicable, this list of conditions and the disclaimer below. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Gabe Black + +from m5.params import * +from m5.SimObject import SimObject + +# ACPI description table header. Subclasses contain and handle the actual +# contents as appropriate for that type of table. +class X86ACPISysDescTable(SimObject): + type = 'X86ACPISysDescTable' + cxx_class = 'X86ISA::ACPI::SysDescTable' + abstract = True + + oem_id = Param.String('', 'string identifying the oem') + oem_table_id = Param.String('', 'oem table ID') + oem_revision = Param.UInt32(0, 'oem revision number for the table') + + creator_id = Param.String('', + 'string identifying the generator of the table') + creator_revision = Param.UInt32(0, + 'revision number for the creator of the table') + +class X86ACPIRSDT(X86ACPISysDescTable): + type = 'X86ACPIRSDT' + cxx_class = 'X86ISA::ACPI::RSDT' + + entries = VectorParam.X86ACPISysDescTable([], 'system description tables') + +class X86ACPIXSDT(X86ACPISysDescTable): + type = 'X86ACPIXSDT' + cxx_class = 'X86ISA::ACPI::XSDT' + + entries = VectorParam.X86ACPISysDescTable([], 'system description tables') + +# Root System Description Pointer Structure +class X86ACPIRSDP(SimObject): + type = 'X86ACPIRSDP' + cxx_class = 'X86ISA::ACPI::RSDP' + + oem_id = Param.String('', 'string identifying the oem') + # Because 0 encodes ACPI 1.0, 2 encodes ACPI 3.0, the version implemented + # here. + revision = Param.UInt8(2, 'revision of ACPI being used, zero indexed') + + rsdt = Param.X86ACPIRSDT('root system description table') + xsdt = Param.X86ACPIXSDT(X86ACPIXSDT(), + 'extended system description table') diff --git a/src/arch/x86/bios/SConscript b/src/arch/x86/bios/SConscript index c4f4f80e6..912d6599c 100644 --- a/src/arch/x86/bios/SConscript +++ b/src/arch/x86/bios/SConscript @@ -71,3 +71,7 @@ if env['TARGET_ISA'] == 'x86': # Intel Multiprocessor Specification Configuration Table SimObject('IntelMP.py') Source('intelmp.cc') + + # ACPI system description tables + SimObject('ACPI.py') + Source('acpi.cc') diff --git a/src/arch/x86/bios/acpi.cc b/src/arch/x86/bios/acpi.cc new file mode 100644 index 000000000..15b3901eb --- /dev/null +++ b/src/arch/x86/bios/acpi.cc @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2008 The Hewlett-Packard Development Company + * All rights reserved. + * + * Redistribution and use of this software in source and binary forms, + * with or without modification, are permitted provided that the + * following conditions are met: + * + * The software must be used only for Non-Commercial Use which means any + * use which is NOT directed to receiving any direct monetary + * compensation for, or commercial advantage from such use. Illustrative + * examples of non-commercial use are academic research, personal study, + * teaching, education and corporate research & development. + * Illustrative examples of commercial use are distributing products for + * commercial advantage and providing services using the software for + * commercial advantage. + * + * If you wish to use this software or functionality therein that may be + * covered by patents for commercial use, please contact: + * Director of Intellectual Property Licensing + * Office of Strategy and Technology + * Hewlett-Packard Company + * 1501 Page Mill Road + * Palo Alto, California 94304 + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. Redistributions + * in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. Neither the name of + * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. No right of + * sublicense is granted herewith. Derivatives of the software and + * output created using the software may be prepared, but only for + * Non-Commercial Uses. Derivatives of the software may be shared with + * others provided: (i) the others agree to abide by the list of + * conditions herein which includes the Non-Commercial Use restrictions; + * and (ii) such Derivatives of the software include the above copyright + * notice to acknowledge the contribution from this software where + * applicable, this list of conditions and the disclaimer below. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#include "arch/x86/bios/acpi.hh" +#include "mem/port.hh" +#include "sim/byteswap.hh" +#include "sim/sim_object.hh" + +#include "params/X86ACPIRSDP.hh" + +#include "params/X86ACPISysDescTable.hh" +#include "params/X86ACPIRSDT.hh" +#include "params/X86ACPIXSDT.hh" + +using namespace std; + +const char X86ISA::ACPI::RSDP::signature[] = "RSD PTR "; + +X86ISA::ACPI::RSDP::RSDP(Params *p) : SimObject(p), oemID(p->oem_id), + revision(p->revision), rsdt(p->rsdt), xsdt(p->xsdt) +{} + +X86ISA::ACPI::SysDescTable::SysDescTable(Params *p, + const char * _signature, uint8_t _revision) : SimObject(p), + signature(_signature), revision(_revision), + oemID(p->oem_id), oemTableID(p->oem_table_id), + oemRevision(p->oem_revision), + creatorID(p->creator_id), creatorRevision(p->creator_revision) +{} + +X86ISA::ACPI::RSDT::RSDT(Params *p) : + SysDescTable(p, "RSDT", 1), entries(p->entries) +{} + +X86ISA::ACPI::XSDT::XSDT(Params *p) : + SysDescTable(p, "XSDT", 1), entries(p->entries) +{} + +X86ISA::ACPI::RSDP * +X86ACPIRSDPParams::create() +{ + return new X86ISA::ACPI::RSDP(this); +} + +X86ISA::ACPI::RSDT * +X86ACPIRSDTParams::create() +{ + return new X86ISA::ACPI::RSDT(this); +} + +X86ISA::ACPI::XSDT * +X86ACPIXSDTParams::create() +{ + return new X86ISA::ACPI::XSDT(this); +} diff --git a/src/arch/x86/bios/acpi.hh b/src/arch/x86/bios/acpi.hh new file mode 100644 index 000000000..7bca17790 --- /dev/null +++ b/src/arch/x86/bios/acpi.hh @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2008 The Hewlett-Packard Development Company + * All rights reserved. + * + * Redistribution and use of this software in source and binary forms, + * with or without modification, are permitted provided that the + * following conditions are met: + * + * The software must be used only for Non-Commercial Use which means any + * use which is NOT directed to receiving any direct monetary + * compensation for, or commercial advantage from such use. Illustrative + * examples of non-commercial use are academic research, personal study, + * teaching, education and corporate research & development. + * Illustrative examples of commercial use are distributing products for + * commercial advantage and providing services using the software for + * commercial advantage. + * + * If you wish to use this software or functionality therein that may be + * covered by patents for commercial use, please contact: + * Director of Intellectual Property Licensing + * Office of Strategy and Technology + * Hewlett-Packard Company + * 1501 Page Mill Road + * Palo Alto, California 94304 + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. Redistributions + * in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. Neither the name of + * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. No right of + * sublicense is granted herewith. Derivatives of the software and + * output created using the software may be prepared, but only for + * Non-Commercial Uses. Derivatives of the software may be shared with + * others provided: (i) the others agree to abide by the list of + * conditions herein which includes the Non-Commercial Use restrictions; + * and (ii) such Derivatives of the software include the above copyright + * notice to acknowledge the contribution from this software where + * applicable, this list of conditions and the disclaimer below. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef __ARCH_X86_BIOS_ACPI_HH__ +#define __ARCH_X86_BIOS_ACPI_HH__ + +#include "sim/host.hh" +#include "sim/sim_object.hh" + +#include +#include + +class Port; + +class X86ACPIRSDPParams; + +class X86ACPISysDescTableParams; +class X86ACPIRSDTParams; +class X86ACPIXSDTParams; + +namespace X86ISA +{ + +namespace ACPI +{ + +class RSDT; +class XSDT; +class SysDescTable; + +class RSDP : public SimObject +{ + protected: + typedef X86ACPIRSDPParams Params; + + static const char signature[]; + + std::string oemID; + uint8_t revision; + + RSDT * rsdt; + XSDT * xsdt; + + public: + RSDP(Params *p); +}; + +class SysDescTable : public SimObject +{ + protected: + typedef X86ACPISysDescTableParams Params; + + const char * signature; + uint8_t revision; + + std::string oemID; + std::string oemTableID; + uint32_t oemRevision; + + std::string creatorID; + uint32_t creatorRevision; + + public: + SysDescTable(Params *p, const char * _signature, uint8_t _revision); +}; + +class RSDT : public SysDescTable +{ + protected: + typedef X86ACPIRSDTParams Params; + + std::vector entries; + + public: + RSDT(Params *p); +}; + +class XSDT : public SysDescTable +{ + protected: + typedef X86ACPIXSDTParams Params; + + std::vector entries; + + public: + XSDT(Params *p); +}; + +} // namespace ACPI + +} // namespace X86ISA + +#endif // __ARCH_X86_BIOS_E820_HH__ diff --git a/src/arch/x86/system.cc b/src/arch/x86/system.cc index b2fadd682..ed3dae4e6 100644 --- a/src/arch/x86/system.cc +++ b/src/arch/x86/system.cc @@ -77,7 +77,8 @@ using namespace X86ISA; X86System::X86System(Params *p) : System(p), smbiosTable(p->smbios_table), mpFloatingPointer(p->intel_mp_pointer), - mpConfigTable(p->intel_mp_table) + mpConfigTable(p->intel_mp_table), + rsdp(p->acpi_description_table_pointer) {} void diff --git a/src/arch/x86/system.hh b/src/arch/x86/system.hh index 7433cc644..12a471f6f 100644 --- a/src/arch/x86/system.hh +++ b/src/arch/x86/system.hh @@ -102,6 +102,7 @@ class X86System : public System X86ISA::SMBios::SMBiosTable * smbiosTable; X86ISA::IntelMP::FloatingPointer * mpFloatingPointer; X86ISA::IntelMP::ConfigTable * mpConfigTable; + X86ISA::ACPI::RSDP * rsdp; void writeOutSMBiosTable(Addr header, Addr &headerSize, Addr &tableSize, Addr table = 0); -- cgit v1.2.3 From 8c5dfa453296c5a87a46c409f68e0ef50ebfceb6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 10 Oct 2008 23:47:42 -0700 Subject: TLB: Make all tlbs derive from a common base class in both python and C++. --- src/arch/alpha/AlphaTLB.py | 5 ++++- src/arch/mips/MipsTLB.py | 4 +++- src/arch/sparc/SparcTLB.py | 5 ++++- src/arch/x86/X86TLB.py | 4 ++-- 4 files changed, 13 insertions(+), 5 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/AlphaTLB.py b/src/arch/alpha/AlphaTLB.py index 7cfb549f3..099327470 100644 --- a/src/arch/alpha/AlphaTLB.py +++ b/src/arch/alpha/AlphaTLB.py @@ -28,7 +28,10 @@ from m5.SimObject import SimObject from m5.params import * -class AlphaTLB(SimObject): + +from BaseTLB import BaseTLB + +class AlphaTLB(BaseTLB): type = 'AlphaTLB' abstract = True size = Param.Int("TLB size") diff --git a/src/arch/mips/MipsTLB.py b/src/arch/mips/MipsTLB.py index 0054acae5..41d46c572 100644 --- a/src/arch/mips/MipsTLB.py +++ b/src/arch/mips/MipsTLB.py @@ -32,7 +32,9 @@ from m5.SimObject import SimObject from m5.params import * -class MipsTLB(SimObject): +from BaseTLB import BaseTLB + +class MipsTLB(BaseTLB): type = 'MipsTLB' abstract = True size = Param.Int("TLB size") diff --git a/src/arch/sparc/SparcTLB.py b/src/arch/sparc/SparcTLB.py index 20672a24e..6758d612a 100644 --- a/src/arch/sparc/SparcTLB.py +++ b/src/arch/sparc/SparcTLB.py @@ -28,7 +28,10 @@ from m5.SimObject import SimObject from m5.params import * -class SparcTLB(SimObject): + +from BaseTLB import BaseTLB + +class SparcTLB(BaseTLB): type = 'SparcTLB' abstract = True size = Param.Int("TLB size") diff --git a/src/arch/x86/X86TLB.py b/src/arch/x86/X86TLB.py index c20566efb..d5ae95372 100644 --- a/src/arch/x86/X86TLB.py +++ b/src/arch/x86/X86TLB.py @@ -54,10 +54,10 @@ # Authors: Gabe Black from MemObject import MemObject -from m5.SimObject import SimObject from m5.params import * from m5.proxy import * from m5 import build_env +from BaseTLB import BaseTLB if build_env['FULL_SYSTEM']: class X86PagetableWalker(MemObject): @@ -66,7 +66,7 @@ if build_env['FULL_SYSTEM']: port = Port("Port for the hardware table walker") system = Param.System(Parent.any, "system object") -class X86TLB(SimObject): +class X86TLB(BaseTLB): type = 'X86TLB' abstract = True size = Param.Int("TLB size") -- cgit v1.2.3 From da7209ec93f3cdad11c02906357f06fa29652996 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 11 Oct 2008 02:27:21 -0700 Subject: CPU: Eliminate the hwrei function. --- src/arch/alpha/ev5.cc | 17 ----------------- src/arch/alpha/isa/decoder.isa | 11 ++++++++++- src/arch/alpha/isa/main.isa | 2 ++ 3 files changed, 12 insertions(+), 18 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index 7dc02a611..eefe86bff 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -552,23 +552,6 @@ copyIprs(ThreadContext *src, ThreadContext *dest) using namespace AlphaISA; -Fault -SimpleThread::hwrei() -{ - if (!(readPC() & 0x3)) - return new UnimplementedOpcodeFault; - - setNextPC(readMiscRegNoEffect(IPR_EXC_ADDR)); - - if (!misspeculating()) { - if (kernelStats) - kernelStats->hwrei(); - } - - // FIXME: XXX check for interrupts? XXX - return NoFault; -} - /** * Check for special simulator handling of specific PAL calls. * If return value is false, actual PAL call will be suppressed. diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index 270940df2..8025ba69f 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -786,7 +786,16 @@ decode OPCODE default Unknown::unknown() { format BasicOperate { 0x1e: decode PALMODE { 0: OpcdecFault::hw_rei(); - 1:hw_rei({{ xc->hwrei(); }}, IsSerializing, IsSerializeBefore); + 1: hw_rei({{ + NPC = ExcAddr; + ThreadContext * tc = xc->tcBase(); + if (!tc->misspeculating()) { + AlphaISA::Kernel::Statistics * kernelStats = + tc->getKernelStats(); + if (kernelStats) + kernelStats->hwrei(); + } + }}, IsSerializing, IsSerializeBefore); } // M5 special opcodes use the reserved 0x01 opcode space diff --git a/src/arch/alpha/isa/main.isa b/src/arch/alpha/isa/main.isa index 5231712c8..078982697 100644 --- a/src/arch/alpha/isa/main.isa +++ b/src/arch/alpha/isa/main.isa @@ -69,6 +69,7 @@ output exec {{ #include #if FULL_SYSTEM +#include "arch/alpha/kernel_stats.hh" #include "sim/pseudo_inst.hh" #endif #include "arch/alpha/ipr.hh" @@ -187,6 +188,7 @@ def operands {{ 'Runiq': ('ControlReg', 'uq', 'MISCREG_UNIQ', None, 1), 'FPCR': ('ControlReg', 'uq', 'MISCREG_FPCR', None, 1), 'IntrFlag': ('ControlReg', 'uq', 'MISCREG_INTR', None, 1), + 'ExcAddr': ('ControlReg', 'uq', 'IPR_EXC_ADDR', None, 1), # The next two are hacks for non-full-system call-pal emulation 'R0': ('IntReg', 'uq', '0', None, 1), 'R16': ('IntReg', 'uq', '16', None, 1), -- cgit v1.2.3 From f621b7b81f0913612381d5dc4993f52bb2116902 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 11 Oct 2008 12:17:24 -0700 Subject: CPU: Eliminate the simPalCheck funciton. --- src/arch/alpha/ev5.cc | 33 --------------------------------- src/arch/alpha/isa/decoder.isa | 23 ++++++++++++++++++++++- src/arch/alpha/isa/main.isa | 1 + 3 files changed, 23 insertions(+), 34 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index eefe86bff..c11b3632e 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -547,36 +547,3 @@ copyIprs(ThreadContext *src, ThreadContext *dest) } } // namespace AlphaISA - -#if FULL_SYSTEM - -using namespace AlphaISA; - -/** - * Check for special simulator handling of specific PAL calls. - * If return value is false, actual PAL call will be suppressed. - */ -bool -SimpleThread::simPalCheck(int palFunc) -{ - if (kernelStats) - kernelStats->callpal(palFunc, tc); - - switch (palFunc) { - case PAL::halt: - halt(); - if (--System::numSystemsRunning == 0) - exitSimLoop("all cpus halted"); - break; - - case PAL::bpt: - case PAL::bugchk: - if (system->breakpoint()) - return false; - break; - } - - return true; -} - -#endif // FULL_SYSTEM diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index 8025ba69f..06676ae87 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -698,7 +698,28 @@ decode OPCODE default Unknown::unknown() { else { // check to see if simulator wants to do something special // on this PAL call (including maybe suppress it) - bool dopal = xc->simPalCheck(palFunc); + + bool dopal = true; + + ThreadContext * tc = xc->tcBase(); + AlphaISA::Kernel::Statistics * kernelStats = tc->getKernelStats(); + System * system = tc->getSystemPtr(); + if (kernelStats) + kernelStats->callpal(palFunc, tc); + + switch (palFunc) { + case PAL::halt: + tc->halt(); + if (--System::numSystemsRunning == 0) + exitSimLoop("all cpus halted"); + break; + + case PAL::bpt: + case PAL::bugchk: + if (system->breakpoint()) + dopal = false; + break; + } if (dopal) { xc->setMiscReg(IPR_EXC_ADDR, NPC); diff --git a/src/arch/alpha/isa/main.isa b/src/arch/alpha/isa/main.isa index 078982697..0f7f74359 100644 --- a/src/arch/alpha/isa/main.isa +++ b/src/arch/alpha/isa/main.isa @@ -70,6 +70,7 @@ output exec {{ #if FULL_SYSTEM #include "arch/alpha/kernel_stats.hh" +#include "arch/alpha/osfpal.hh" #include "sim/pseudo_inst.hh" #endif #include "arch/alpha/ipr.hh" -- cgit v1.2.3 From 526933e5d03f5d7963bc5a244294ddbb068c4770 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 11 Oct 2008 15:14:37 -0700 Subject: X86: Add an Intel MP table to the simulation. --- src/arch/x86/bios/IntelMP.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/bios/IntelMP.py b/src/arch/x86/bios/IntelMP.py index 70e7963fa..758932180 100644 --- a/src/arch/x86/bios/IntelMP.py +++ b/src/arch/x86/bios/IntelMP.py @@ -86,6 +86,15 @@ class X86IntelMPConfigTable(SimObject): ext_entries = VectorParam.X86IntelMPExtConfigEntry([], 'extended configuration table entries') + def add_entry(self, entry): + if isinstance(entry, X86IntelMPBaseConfigEntry): + self.base_entries.append(entry) + elif isinstance(entry, X86IntelMPExtConfigEntry): + self.base_entries.append(entry) + else: + panic("Don't know what type of Intel MP entry %s is." \ + % entry.__class__.__name__) + class X86IntelMPBaseConfigEntry(SimObject): type = 'X86IntelMPBaseConfigEntry' cxx_class = 'X86ISA::IntelMP::BaseConfigEntry' -- cgit v1.2.3 From c4f1cc3b482311f878be44259125c9a5b90c0569 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 08:24:09 -0700 Subject: CPU: Eliminate the get_vec function. --- src/arch/alpha/interrupts.hh | 7 ------- src/arch/mips/interrupts.cc | 12 ------------ src/arch/mips/interrupts.hh | 4 ---- src/arch/sparc/tlb.cc | 33 ++++++++++++++++++++++++--------- src/arch/x86/interrupts.hh | 6 ------ 5 files changed, 24 insertions(+), 38 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/interrupts.hh b/src/arch/alpha/interrupts.hh index abfecfb5b..6ae4e4b1d 100644 --- a/src/arch/alpha/interrupts.hh +++ b/src/arch/alpha/interrupts.hh @@ -171,13 +171,6 @@ class Interrupts tc->setMiscRegNoEffect(IPR_INTID, newIpl); newInfoSet = false; } - - uint64_t - get_vec(int int_num) - { - panic("Shouldn't be called for Alpha\n"); - M5_DUMMY_RETURN; - } }; } // namespace AlphaISA diff --git a/src/arch/mips/interrupts.cc b/src/arch/mips/interrupts.cc index c91ee1e99..e04d22631 100755 --- a/src/arch/mips/interrupts.cc +++ b/src/arch/mips/interrupts.cc @@ -156,12 +156,6 @@ static inline void setCauseIP_(ThreadContext *tc, uint8_t val) { return false; } - - uint64_t Interrupts::get_vec(int int_num) - { - panic("MipsISA::Interrupts::get_vec() is not implemented. \n"); - M5_DUMMY_RETURN - } */ void Interrupts::post(int int_num, ThreadContext* tc) { @@ -252,12 +246,6 @@ void Interrupts::updateIntrInfo(ThreadContext *tc) const ; } -uint64_t Interrupts::get_vec(int int_num) -{ - panic("MipsISA::Interrupts::get_vec() is not implemented. \n"); - M5_DUMMY_RETURN - } - bool Interrupts::interruptsPending(ThreadContext *tc) const { //if there is a on cpu timer interrupt (i.e. Compare == Count) diff --git a/src/arch/mips/interrupts.hh b/src/arch/mips/interrupts.hh index f0e928088..99a8f6fa0 100755 --- a/src/arch/mips/interrupts.hh +++ b/src/arch/mips/interrupts.hh @@ -91,8 +91,6 @@ class Interrupts void updateIntrInfoCpuTimerIntr(ThreadContext *tc) const; bool onCpuTimerInterrupt(ThreadContext *tc) const; - uint64_t get_vec(int int_num); - bool check_interrupts(ThreadContext * tc) const{ //return (intstatus != 0) && !(tc->readPC() & 0x3); if (oncputimerintr == false){ @@ -160,8 +158,6 @@ class Interrupts bool interruptsPending(ThreadContext *tc) const; bool onCpuTimerInterrupt(ThreadContext *tc) const; - uint64_t get_vec(int int_num); - bool check_interrupts(ThreadContext * tc) const{ return interruptsPending(tc); } diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index 125ceba69..61f0985db 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -1008,12 +1008,22 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) itb->cx_config)); break; case ASI_SWVR_INTR_RECEIVE: - pkt->set(tc->getCpuPtr()->get_interrupts(IT_INT_VEC)); + { + SparcISA::Interrupts * interrupts = + dynamic_cast( + tc->getCpuPtr()->getInterruptController()); + pkt->set(interrupts->get_vec(IT_INT_VEC)); + } break; case ASI_SWVR_UDB_INTR_R: - temp = findMsbSet(tc->getCpuPtr()->get_interrupts(IT_INT_VEC)); - tc->getCpuPtr()->clear_interrupt(IT_INT_VEC, temp); - pkt->set(temp); + { + SparcISA::Interrupts * interrupts = + dynamic_cast( + tc->getCpuPtr()->getInterruptController()); + temp = findMsbSet(interrupts->get_vec(IT_INT_VEC)); + tc->getCpuPtr()->clear_interrupt(IT_INT_VEC, temp); + pkt->set(temp); + } break; default: doMmuReadError: @@ -1252,11 +1262,16 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) } break; case ASI_SWVR_INTR_RECEIVE: - int msb; - // clear all the interrupts that aren't set in the write - while(tc->getCpuPtr()->get_interrupts(IT_INT_VEC) & data) { - msb = findMsbSet(tc->getCpuPtr()->get_interrupts(IT_INT_VEC) & data); - tc->getCpuPtr()->clear_interrupt(IT_INT_VEC, msb); + { + int msb; + // clear all the interrupts that aren't set in the write + SparcISA::Interrupts * interrupts = + dynamic_cast( + tc->getCpuPtr()->getInterruptController()); + while(interrupts->get_vec(IT_INT_VEC) & data) { + msb = findMsbSet(interrupts->get_vec(IT_INT_VEC) & data); + tc->getCpuPtr()->clear_interrupt(IT_INT_VEC, msb); + } } break; case ASI_SWVR_UDB_INTR_W: diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh index cf9109e22..43675294e 100644 --- a/src/arch/x86/interrupts.hh +++ b/src/arch/x86/interrupts.hh @@ -108,12 +108,6 @@ class Interrupts panic("Interrupts::updateIntrInfo unimplemented!\n"); } - uint64_t get_vec(int int_num) - { - panic("Interrupts::get_vec unimplemented!\n"); - return 0; - } - void serialize(std::ostream & os) { panic("Interrupts::serialize unimplemented!\n"); -- cgit v1.2.3 From d9f9c967fbe651e09d444e460a9b1c5a450b1cd2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 09:09:56 -0700 Subject: Turn Interrupts objects into SimObjects. Also, move local APIC state into x86's Interrupts object. --- src/arch/alpha/AlphaInterrupts.py | 33 ++++++ src/arch/alpha/SConscript | 2 + src/arch/alpha/interrupts.cc | 37 +++++++ src/arch/alpha/interrupts.hh | 15 ++- src/arch/mips/MipsInterrupts.py | 33 ++++++ src/arch/mips/SConscript | 1 + src/arch/sparc/SConscript | 2 + src/arch/sparc/SparcInterrupts.py | 33 ++++++ src/arch/sparc/interrupts.cc | 37 +++++++ src/arch/sparc/interrupts.hh | 14 ++- src/arch/x86/SConscript | 2 + src/arch/x86/X86LocalApic.py | 35 ++++++ src/arch/x86/apicregs.hh | 91 +++++++++++++++ src/arch/x86/interrupts.cc | 227 ++++++++++++++++++++++++++++++++++++++ src/arch/x86/interrupts.hh | 44 +++++++- src/arch/x86/miscregfile.cc | 172 +++++------------------------ src/arch/x86/miscregfile.hh | 21 +--- src/arch/x86/miscregs.hh | 59 ++-------- src/arch/x86/mmaped_ipr.hh | 7 +- src/arch/x86/regfile.cc | 8 +- src/arch/x86/tlb.cc | 52 +++++---- src/arch/x86/utility.cc | 14 ++- 22 files changed, 689 insertions(+), 250 deletions(-) create mode 100644 src/arch/alpha/AlphaInterrupts.py create mode 100644 src/arch/alpha/interrupts.cc create mode 100644 src/arch/mips/MipsInterrupts.py create mode 100644 src/arch/sparc/SparcInterrupts.py create mode 100644 src/arch/sparc/interrupts.cc create mode 100644 src/arch/x86/X86LocalApic.py create mode 100644 src/arch/x86/apicregs.hh create mode 100644 src/arch/x86/interrupts.cc (limited to 'src/arch') diff --git a/src/arch/alpha/AlphaInterrupts.py b/src/arch/alpha/AlphaInterrupts.py new file mode 100644 index 000000000..ecfcf5c21 --- /dev/null +++ b/src/arch/alpha/AlphaInterrupts.py @@ -0,0 +1,33 @@ +# Copyright (c) 2008 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Gabe Black + +from m5.SimObject import SimObject + +class AlphaInterrupts(SimObject): + type = 'AlphaInterrupts' + cxx_class = 'AlphaISA::Interrupts' diff --git a/src/arch/alpha/SConscript b/src/arch/alpha/SConscript index 04bac3996..069db2551 100644 --- a/src/arch/alpha/SConscript +++ b/src/arch/alpha/SConscript @@ -47,9 +47,11 @@ if env['TARGET_ISA'] == 'alpha': SimObject('AlphaTLB.py') if env['FULL_SYSTEM']: + SimObject('AlphaInterrupts.py') SimObject('AlphaSystem.py') Source('idle_event.cc') + Source('interrupts.cc') Source('kernel_stats.cc') Source('osfpal.cc') Source('stacktrace.cc') diff --git a/src/arch/alpha/interrupts.cc b/src/arch/alpha/interrupts.cc new file mode 100644 index 000000000..4b5dc5661 --- /dev/null +++ b/src/arch/alpha/interrupts.cc @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2008 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#include "arch/alpha/interrupts.hh" + +AlphaISA::Interrupts * +AlphaInterruptsParams::create() +{ + return new AlphaISA::Interrupts(this); +} diff --git a/src/arch/alpha/interrupts.hh b/src/arch/alpha/interrupts.hh index 6ae4e4b1d..e7a451d4d 100644 --- a/src/arch/alpha/interrupts.hh +++ b/src/arch/alpha/interrupts.hh @@ -35,11 +35,14 @@ #include "arch/alpha/faults.hh" #include "arch/alpha/isa_traits.hh" #include "base/compiler.hh" +#include "base/trace.hh" #include "cpu/thread_context.hh" +#include "params/AlphaInterrupts.hh" +#include "sim/sim_object.hh" namespace AlphaISA { -class Interrupts +class Interrupts : public SimObject { private: bool newInfoSet; @@ -51,7 +54,15 @@ class Interrupts uint64_t intstatus; public: - Interrupts() + typedef AlphaInterruptsParams Params; + + const Params * + params() const + { + return dynamic_cast(_params); + } + + Interrupts(Params * p) : SimObject(p) { memset(interrupts, 0, sizeof(interrupts)); intstatus = 0; diff --git a/src/arch/mips/MipsInterrupts.py b/src/arch/mips/MipsInterrupts.py new file mode 100644 index 000000000..06cd54263 --- /dev/null +++ b/src/arch/mips/MipsInterrupts.py @@ -0,0 +1,33 @@ +# Copyright (c) 2008 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Gabe Black + +from m5.SimObject import SimObject + +class MipsInterrupts(SimObject): + type = 'MipsInterrupts' + cxx_class = 'MipsISA::Interrupts' diff --git a/src/arch/mips/SConscript b/src/arch/mips/SConscript index 844e7ba15..0368e68bc 100644 --- a/src/arch/mips/SConscript +++ b/src/arch/mips/SConscript @@ -51,6 +51,7 @@ if env['TARGET_ISA'] == 'mips': if env['FULL_SYSTEM']: SimObject('MipsSystem.py') + SimObject('MipsInterrupts.py') Source('idle_event.cc') Source('mips_core_specific.cc') Source('vtophys.cc') diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript index d4d68a6bd..126587835 100644 --- a/src/arch/sparc/SConscript +++ b/src/arch/sparc/SConscript @@ -52,7 +52,9 @@ if env['TARGET_ISA'] == 'sparc': if env['FULL_SYSTEM']: SimObject('SparcSystem.py') + SimObject('SparcInterrupts.py') + Source('interrupts.cc') Source('stacktrace.cc') Source('system.cc') Source('ua2005.cc') diff --git a/src/arch/sparc/SparcInterrupts.py b/src/arch/sparc/SparcInterrupts.py new file mode 100644 index 000000000..2cc964c2d --- /dev/null +++ b/src/arch/sparc/SparcInterrupts.py @@ -0,0 +1,33 @@ +# Copyright (c) 2008 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Gabe Black + +from m5.SimObject import SimObject + +class SparcInterrupts(SimObject): + type = 'SparcInterrupts' + cxx_class = 'SparcISA::Interrupts' diff --git a/src/arch/sparc/interrupts.cc b/src/arch/sparc/interrupts.cc new file mode 100644 index 000000000..96d61e559 --- /dev/null +++ b/src/arch/sparc/interrupts.cc @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2008 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#include "arch/sparc/interrupts.hh" + +SparcISA::Interrupts * +SparcInterruptsParams::create() +{ + return new SparcISA::Interrupts(this); +} diff --git a/src/arch/sparc/interrupts.hh b/src/arch/sparc/interrupts.hh index 4ad3385fb..7d1496d8e 100644 --- a/src/arch/sparc/interrupts.hh +++ b/src/arch/sparc/interrupts.hh @@ -35,11 +35,13 @@ #include "arch/sparc/faults.hh" #include "arch/sparc/isa_traits.hh" #include "cpu/thread_context.hh" +#include "params/SparcInterrupts.hh" +#include "sim/sim_object.hh" namespace SparcISA { -class Interrupts +class Interrupts : public SimObject { private: @@ -48,7 +50,15 @@ class Interrupts uint64_t intStatus; public: - Interrupts() + typedef SparcInterruptsParams Params; + + const Params * + params() const + { + return dynamic_cast(_params); + } + + Interrupts(Params * p) : SimObject(p) { clear_all(); } diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript index 0d8760fdc..e019b77c9 100644 --- a/src/arch/x86/SConscript +++ b/src/arch/x86/SConscript @@ -109,9 +109,11 @@ if env['TARGET_ISA'] == 'x86': TraceFlag('X86') if env['FULL_SYSTEM']: + SimObject('X86LocalApic.py') SimObject('X86System.py') # Full-system sources + Source('interrupts.cc') Source('linux/system.cc') Source('pagetable_walker.cc') Source('system.cc') diff --git a/src/arch/x86/X86LocalApic.py b/src/arch/x86/X86LocalApic.py new file mode 100644 index 000000000..94e32ae50 --- /dev/null +++ b/src/arch/x86/X86LocalApic.py @@ -0,0 +1,35 @@ +# Copyright (c) 2008 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Gabe Black + +from m5.params import * +from Device import BasicPioDevice + +class X86LocalApic(BasicPioDevice): + type = 'X86LocalApic' + cxx_class = 'X86ISA::Interrupts' + pio_latency = Param.Latency('1ns', 'Programmed IO latency in simticks') diff --git a/src/arch/x86/apicregs.hh b/src/arch/x86/apicregs.hh new file mode 100644 index 000000000..464c3af2d --- /dev/null +++ b/src/arch/x86/apicregs.hh @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2008 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef __ARCH_X86_APICREGS_HH__ +#define __ARCH_X86_APICREGS_HH__ + +namespace X86ISA +{ + enum ApicRegIndex + { + APIC_ID, + APIC_VERSION, + APIC_TASK_PRIORITY, + APIC_ARBITRATION_PRIORITY, + APIC_PROCESSOR_PRIORITY, + APIC_EOI, + APIC_LOGICAL_DESTINATION, + APIC_DESTINATION_FORMAT, + APIC_SPURIOUS_INTERRUPT_VECTOR, + + APIC_IN_SERVICE_BASE, + + APIC_TRIGGER_MODE_BASE = APIC_IN_SERVICE_BASE + 16, + + APIC_INTERRUPT_REQUEST_BASE = APIC_TRIGGER_MODE_BASE + 16, + + APIC_ERROR_STATUS = APIC_INTERRUPT_REQUEST_BASE + 16, + APIC_INTERRUPT_COMMAND_LOW, + APIC_INTERRUPT_COMMAND_HIGH, + APIC_LVT_TIMER, + APIC_LVT_THERMAL_SENSOR, + APIC_LVT_PERFORMANCE_MONITORING_COUNTERS, + APIC_LVT_LINT0, + APIC_LVT_LINT1, + APIC_LVT_ERROR, + APIC_INITIAL_COUNT, + APIC_CURRENT_COUNT, + APIC_DIVIDE_CONFIGURATION, + + APIC_INTERNAL_STATE, + + NUM_APIC_REGS + }; + + static inline ApicRegIndex + APIC_IN_SERVICE(int index) + { + return (ApicRegIndex)(APIC_IN_SERVICE_BASE + index); + } + + static inline ApicRegIndex + APIC_TRIGGER_MODE(int index) + { + return (ApicRegIndex)(APIC_TRIGGER_MODE_BASE + index); + } + + static inline ApicRegIndex + APIC_INTERRUPT_REQUEST(int index) + { + return (ApicRegIndex)(APIC_INTERRUPT_REQUEST_BASE + index); + } +} + +#endif diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc new file mode 100644 index 000000000..73536f2b4 --- /dev/null +++ b/src/arch/x86/interrupts.cc @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2008 The Hewlett-Packard Development Company + * All rights reserved. + * + * Redistribution and use of this software in source and binary forms, + * with or without modification, are permitted provided that the + * following conditions are met: + * + * The software must be used only for Non-Commercial Use which means any + * use which is NOT directed to receiving any direct monetary + * compensation for, or commercial advantage from such use. Illustrative + * examples of non-commercial use are academic research, personal study, + * teaching, education and corporate research & development. + * Illustrative examples of commercial use are distributing products for + * commercial advantage and providing services using the software for + * commercial advantage. + * + * If you wish to use this software or functionality therein that may be + * covered by patents for commercial use, please contact: + * Director of Intellectual Property Licensing + * Office of Strategy and Technology + * Hewlett-Packard Company + * 1501 Page Mill Road + * Palo Alto, California 94304 + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. Redistributions + * in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. Neither the name of + * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. No right of + * sublicense is granted herewith. Derivatives of the software and + * output created using the software may be prepared, but only for + * Non-Commercial Uses. Derivatives of the software may be shared with + * others provided: (i) the others agree to abide by the list of + * conditions herein which includes the Non-Commercial Use restrictions; + * and (ii) such Derivatives of the software include the above copyright + * notice to acknowledge the contribution from this software where + * applicable, this list of conditions and the disclaimer below. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#include "arch/x86/interrupts.hh" +#include "cpu/base.hh" + +int divideFromConf(uint32_t conf) +{ + // This figures out what division we want from the division configuration + // register in the local APIC. The encoding is a little odd but it can + // be deciphered fairly easily. + int shift = ((conf & 0x8) >> 1) | (conf & 0x3); + shift = (shift + 1) % 8; + return 1 << shift; +} + +uint32_t +X86ISA::Interrupts::readRegNoEffect(ApicRegIndex reg) +{ + return regs[reg]; +} + +uint32_t +X86ISA::Interrupts::readReg(ApicRegIndex reg, ThreadContext * tc) +{ + if (reg >= APIC_TRIGGER_MODE(0) && + reg <= APIC_TRIGGER_MODE(15)) { + panic("Local APIC Trigger Mode registers are unimplemented.\n"); + } + switch (reg) { + case APIC_ARBITRATION_PRIORITY: + panic("Local APIC Arbitration Priority register unimplemented.\n"); + break; + case APIC_PROCESSOR_PRIORITY: + panic("Local APIC Processor Priority register unimplemented.\n"); + break; + case APIC_EOI: + panic("Local APIC EOI register unimplemented.\n"); + break; + case APIC_ERROR_STATUS: + regs[APIC_INTERNAL_STATE] &= ~ULL(0x1); + break; + case APIC_INTERRUPT_COMMAND_LOW: + panic("Local APIC Interrupt Command low" + " register unimplemented.\n"); + break; + case APIC_INTERRUPT_COMMAND_HIGH: + panic("Local APIC Interrupt Command high" + " register unimplemented.\n"); + break; + case APIC_CURRENT_COUNT: + { + uint32_t val = regs[reg] - tc->getCpuPtr()->curCycle(); + val /= (16 * divideFromConf(regs[APIC_DIVIDE_CONFIGURATION])); + return val; + } + default: + break; + } + return readRegNoEffect(reg); +} + +void +X86ISA::Interrupts::setRegNoEffect(ApicRegIndex reg, uint32_t val) +{ + regs[reg] = val; +} + +void +X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val, ThreadContext *tc) +{ + uint32_t newVal = val; + if (reg >= APIC_IN_SERVICE(0) && + reg <= APIC_IN_SERVICE(15)) { + panic("Local APIC In-Service registers are unimplemented.\n"); + } + if (reg >= APIC_TRIGGER_MODE(0) && + reg <= APIC_TRIGGER_MODE(15)) { + panic("Local APIC Trigger Mode registers are unimplemented.\n"); + } + if (reg >= APIC_INTERRUPT_REQUEST(0) && + reg <= APIC_INTERRUPT_REQUEST(15)) { + panic("Local APIC Interrupt Request registers " + "are unimplemented.\n"); + } + switch (reg) { + case APIC_ID: + newVal = val & 0xFF; + break; + case APIC_VERSION: + // The Local APIC Version register is read only. + return; + case APIC_TASK_PRIORITY: + newVal = val & 0xFF; + break; + case APIC_ARBITRATION_PRIORITY: + panic("Local APIC Arbitration Priority register unimplemented.\n"); + break; + case APIC_PROCESSOR_PRIORITY: + panic("Local APIC Processor Priority register unimplemented.\n"); + break; + case APIC_EOI: + panic("Local APIC EOI register unimplemented.\n"); + break; + case APIC_LOGICAL_DESTINATION: + newVal = val & 0xFF000000; + break; + case APIC_DESTINATION_FORMAT: + newVal = val | 0x0FFFFFFF; + break; + case APIC_SPURIOUS_INTERRUPT_VECTOR: + regs[APIC_INTERNAL_STATE] &= ~ULL(1 << 1); + regs[APIC_INTERNAL_STATE] |= val & (1 << 8); + if (val & (1 << 9)) + warn("Focus processor checking not implemented.\n"); + break; + case APIC_ERROR_STATUS: + { + if (regs[APIC_INTERNAL_STATE] & 0x1) { + regs[APIC_INTERNAL_STATE] &= ~ULL(0x1); + newVal = 0; + } else { + regs[APIC_INTERNAL_STATE] |= ULL(0x1); + return; + } + + } + break; + case APIC_INTERRUPT_COMMAND_LOW: + panic("Local APIC Interrupt Command low" + " register unimplemented.\n"); + break; + case APIC_INTERRUPT_COMMAND_HIGH: + panic("Local APIC Interrupt Command high" + " register unimplemented.\n"); + break; + case APIC_LVT_TIMER: + case APIC_LVT_THERMAL_SENSOR: + case APIC_LVT_PERFORMANCE_MONITORING_COUNTERS: + case APIC_LVT_LINT0: + case APIC_LVT_LINT1: + case APIC_LVT_ERROR: + { + uint64_t readOnlyMask = (1 << 12) | (1 << 14); + newVal = (val & ~readOnlyMask) | + (regs[reg] & readOnlyMask); + } + break; + case APIC_INITIAL_COUNT: + newVal = bits(val, 31, 0); + regs[APIC_CURRENT_COUNT] = + tc->getCpuPtr()->curCycle() + + (16 * divideFromConf(regs[APIC_DIVIDE_CONFIGURATION])) * newVal; + //FIXME This should schedule the timer event. + break; + case APIC_CURRENT_COUNT: + //Local APIC Current Count register is read only. + return; + case APIC_DIVIDE_CONFIGURATION: + newVal = val & 0xB; + break; + default: + break; + } + setRegNoEffect(reg, newVal); + return; +} + +X86ISA::Interrupts * +X86LocalApicParams::create() +{ + return new X86ISA::Interrupts(this); +} diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh index 43675294e..68bb2e07d 100644 --- a/src/arch/x86/interrupts.hh +++ b/src/arch/x86/interrupts.hh @@ -58,17 +58,57 @@ #ifndef __ARCH_X86_INTERRUPTS_HH__ #define __ARCH_X86_INTERRUPTS_HH__ +#include "arch/x86/apicregs.hh" #include "arch/x86/faults.hh" #include "cpu/thread_context.hh" +#include "params/X86LocalApic.hh" +#include "sim/eventq.hh" +#include "sim/sim_object.hh" + +class ThreadContext; namespace X86ISA { -class Interrupts +class Interrupts : public SimObject { + protected: + uint32_t regs[NUM_APIC_REGS]; + + class ApicTimerEvent : public Event + { + public: + ApicTimerEvent() : Event() + {} + + void process() + { + warn("Local APIC timer event doesn't do anything!\n"); + } + }; + + ApicTimerEvent apicTimerEvent; + public: - Interrupts() + typedef X86LocalApicParams Params; + + const Params * + params() const + { + return dynamic_cast(_params); + } + + uint32_t readRegNoEffect(ApicRegIndex reg); + uint32_t readReg(ApicRegIndex miscReg, ThreadContext *tc); + + void setRegNoEffect(ApicRegIndex reg, uint32_t val); + void setReg(ApicRegIndex reg, uint32_t val, ThreadContext *tc); + + Interrupts(Params * p) : SimObject(p) { + //Set the local apic DFR to the flat model. + regs[APIC_DESTINATION_FORMAT] = (uint32_t)(-1); + memset(regs, 0, sizeof(regs)); clear_all(); } diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc index f40b1adf5..aba498616 100644 --- a/src/arch/x86/miscregfile.cc +++ b/src/arch/x86/miscregfile.cc @@ -106,21 +106,9 @@ void MiscRegFile::clear() { // Blank everything. 0 might not be an appropriate value for some things. memset(regVal, 0, NumMiscRegs * sizeof(MiscReg)); - //Set the local apic DFR to the flat model. - regVal[MISCREG_APIC_DESTINATION_FORMAT] = (MiscReg)(-1); } -int divideFromConf(MiscReg conf) -{ - // This figures out what division we want from the division configuration - // register in the local APIC. The encoding is a little odd but it can - // be deciphered fairly easily. - int shift = ((conf & 0x8) >> 1) | (conf & 0x3); - shift = (shift + 1) % 8; - return 1 << shift; -}; - -MiscReg MiscRegFile::readRegNoEffect(int miscReg) +MiscReg MiscRegFile::readRegNoEffect(MiscRegIndex miscReg) { // Make sure we're not dealing with an illegal control register. // Instructions should filter out these indexes, and nothing else should @@ -131,52 +119,30 @@ MiscReg MiscRegFile::readRegNoEffect(int miscReg) !(miscReg > MISCREG_CR8 && miscReg <= MISCREG_CR15)); + if (isApicReg(miscReg)) { + panic("Can't readRegNoEffect from the local APIC.\n"); + } return regVal[miscReg]; } -MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc) +MiscReg MiscRegFile::readReg(MiscRegIndex miscReg, ThreadContext * tc) { - if (miscReg >= MISCREG_APIC_START && miscReg <= MISCREG_APIC_END) { - if (miscReg >= MISCREG_APIC_TRIGGER_MODE(0) && - miscReg <= MISCREG_APIC_TRIGGER_MODE(15)) { - panic("Local APIC Trigger Mode registers are unimplemented.\n"); - } - switch (miscReg) { - case MISCREG_APIC_ARBITRATION_PRIORITY: - panic("Local APIC Arbitration Priority register unimplemented.\n"); - break; - case MISCREG_APIC_PROCESSOR_PRIORITY: - panic("Local APIC Processor Priority register unimplemented.\n"); - break; - case MISCREG_APIC_EOI: - panic("Local APIC EOI register unimplemented.\n"); - break; - case MISCREG_APIC_ERROR_STATUS: - regVal[MISCREG_APIC_INTERNAL_STATE] &= ~ULL(0x1); - break; - case MISCREG_APIC_INTERRUPT_COMMAND_LOW: - panic("Local APIC Interrupt Command low" - " register unimplemented.\n"); - break; - case MISCREG_APIC_INTERRUPT_COMMAND_HIGH: - panic("Local APIC Interrupt Command high" - " register unimplemented.\n"); - break; - case MISCREG_APIC_CURRENT_COUNT: - return (regVal[miscReg] - tc->getCpuPtr()->curCycle()) / - (16 * divideFromConf( - regVal[MISCREG_APIC_DIVIDE_CONFIGURATION])); - break; - } +#if FULL_SYSTEM + if (isApicReg(miscReg)) { + Interrupts * interrupts = dynamic_cast( + tc->getCpuPtr()->getInterruptController()); + assert(interrupts); + return interrupts->readReg( + (ApicRegIndex)(miscReg - MISCREG_APIC_START), tc); } - switch (miscReg) { - case MISCREG_TSC: +#endif + if (miscReg == MISCREG_TSC) { return regVal[MISCREG_TSC] + tc->getCpuPtr()->curCycle(); } return readRegNoEffect(miscReg); } -void MiscRegFile::setRegNoEffect(int miscReg, const MiscReg &val) +void MiscRegFile::setRegNoEffect(MiscRegIndex miscReg, const MiscReg &val) { // Make sure we're not dealing with an illegal control register. // Instructions should filter out these indexes, and nothing else should @@ -186,108 +152,26 @@ void MiscRegFile::setRegNoEffect(int miscReg, const MiscReg &val) miscReg < MISCREG_CR8) && !(miscReg > MISCREG_CR8 && miscReg <= MISCREG_CR15)); + if (isApicReg(miscReg)) { + panic("Can't setRegNoEffect from the local APIC.\n"); + } regVal[miscReg] = val; } -void MiscRegFile::setReg(int miscReg, +void MiscRegFile::setReg(MiscRegIndex miscReg, const MiscReg &val, ThreadContext * tc) { MiscReg newVal = val; - if (miscReg >= MISCREG_APIC_START && miscReg <= MISCREG_APIC_END) { - if (miscReg >= MISCREG_APIC_IN_SERVICE(0) && - miscReg <= MISCREG_APIC_IN_SERVICE(15)) { - panic("Local APIC In-Service registers are unimplemented.\n"); - } - if (miscReg >= MISCREG_APIC_TRIGGER_MODE(0) && - miscReg <= MISCREG_APIC_TRIGGER_MODE(15)) { - panic("Local APIC Trigger Mode registers are unimplemented.\n"); - } - if (miscReg >= MISCREG_APIC_INTERRUPT_REQUEST(0) && - miscReg <= MISCREG_APIC_INTERRUPT_REQUEST(15)) { - panic("Local APIC Interrupt Request registers " - "are unimplemented.\n"); - } - switch (miscReg) { - case MISCREG_APIC_ID: - newVal = val & 0xFF; - break; - case MISCREG_APIC_VERSION: - // The Local APIC Version register is read only. - return; - case MISCREG_APIC_TASK_PRIORITY: - newVal = val & 0xFF; - break; - case MISCREG_APIC_ARBITRATION_PRIORITY: - panic("Local APIC Arbitration Priority register unimplemented.\n"); - break; - case MISCREG_APIC_PROCESSOR_PRIORITY: - panic("Local APIC Processor Priority register unimplemented.\n"); - break; - case MISCREG_APIC_EOI: - panic("Local APIC EOI register unimplemented.\n"); - break; - case MISCREG_APIC_LOGICAL_DESTINATION: - newVal = val & 0xFF000000; - break; - case MISCREG_APIC_DESTINATION_FORMAT: - newVal = val | 0x0FFFFFFF; - break; - case MISCREG_APIC_SPURIOUS_INTERRUPT_VECTOR: - regVal[MISCREG_APIC_INTERNAL_STATE] &= ~ULL(1 << 1); - regVal[MISCREG_APIC_INTERNAL_STATE] |= val & (1 << 8); - if (val & (1 << 9)) - warn("Focus processor checking not implemented.\n"); - break; - case MISCREG_APIC_ERROR_STATUS: - { - if (regVal[MISCREG_APIC_INTERNAL_STATE] & 0x1) { - regVal[MISCREG_APIC_INTERNAL_STATE] &= ~ULL(0x1); - newVal = 0; - } else { - regVal[MISCREG_APIC_INTERNAL_STATE] |= ULL(0x1); - return; - } - - } - break; - case MISCREG_APIC_INTERRUPT_COMMAND_LOW: - panic("Local APIC Interrupt Command low" - " register unimplemented.\n"); - break; - case MISCREG_APIC_INTERRUPT_COMMAND_HIGH: - panic("Local APIC Interrupt Command high" - " register unimplemented.\n"); - break; - case MISCREG_APIC_LVT_TIMER: - case MISCREG_APIC_LVT_THERMAL_SENSOR: - case MISCREG_APIC_LVT_PERFORMANCE_MONITORING_COUNTERS: - case MISCREG_APIC_LVT_LINT0: - case MISCREG_APIC_LVT_LINT1: - case MISCREG_APIC_LVT_ERROR: - { - uint64_t readOnlyMask = (1 << 12) | (1 << 14); - newVal = (val & ~readOnlyMask) | - (regVal[miscReg] & readOnlyMask); - } - break; - case MISCREG_APIC_INITIAL_COUNT: - newVal = bits(val, 31, 0); - regVal[MISCREG_APIC_CURRENT_COUNT] = - tc->getCpuPtr()->curCycle() + - (16 * divideFromConf( - regVal[MISCREG_APIC_DIVIDE_CONFIGURATION])) * newVal; - //FIXME This should schedule the timer event. - break; - case MISCREG_APIC_CURRENT_COUNT: - //Local APIC Current Count register is read only. - return; - case MISCREG_APIC_DIVIDE_CONFIGURATION: - newVal = val & 0xB; - break; - } - setRegNoEffect(miscReg, newVal); +#if FULL_SYSTEM + if (isApicReg(miscReg)) { + Interrupts * interrupts = dynamic_cast( + tc->getCpuPtr()->getInterruptController()); + assert(interrupts); + interrupts->setReg( + ApicRegIndex(miscReg - MISCREG_APIC_START), val, tc); return; } +#endif switch(miscReg) { case MISCREG_CR0: @@ -408,6 +292,8 @@ void MiscRegFile::setReg(int miscReg, case MISCREG_TSC: regVal[MISCREG_TSC] = val - tc->getCpuPtr()->curCycle(); return; + default: + break; } setRegNoEffect(miscReg, newVal); } diff --git a/src/arch/x86/miscregfile.hh b/src/arch/x86/miscregfile.hh index 21caf3aa1..e59b8d3b1 100644 --- a/src/arch/x86/miscregfile.hh +++ b/src/arch/x86/miscregfile.hh @@ -91,7 +91,6 @@ #include "arch/x86/faults.hh" #include "arch/x86/miscregs.hh" #include "arch/x86/types.hh" -#include "sim/eventq.hh" #include "sim/host.hh" #include @@ -112,18 +111,6 @@ namespace X86ISA protected: MiscReg regVal[NumMiscRegs]; - class ApicTimerEvent : public Event - { - public: - void - process() - { - warn("Local APIC timer event doesn't do anything!\n"); - } - }; - - ApicTimerEvent apicTimerEvent; - public: void clear(); @@ -132,13 +119,13 @@ namespace X86ISA clear(); } - MiscReg readRegNoEffect(int miscReg); + MiscReg readRegNoEffect(MiscRegIndex miscReg); - MiscReg readReg(int miscReg, ThreadContext *tc); + MiscReg readReg(MiscRegIndex miscReg, ThreadContext *tc); - void setRegNoEffect(int miscReg, const MiscReg &val); + void setRegNoEffect(MiscRegIndex miscReg, const MiscReg &val); - void setReg(int miscReg, + void setReg(MiscRegIndex miscReg, const MiscReg &val, ThreadContext *tc); void serialize(std::ostream & os); diff --git a/src/arch/x86/miscregs.hh b/src/arch/x86/miscregs.hh index 5a6ee752d..dbf08ec5d 100644 --- a/src/arch/x86/miscregs.hh +++ b/src/arch/x86/miscregs.hh @@ -58,6 +58,7 @@ #ifndef __ARCH_X86_MISCREGS_HH__ #define __ARCH_X86_MISCREGS_HH__ +#include "arch/x86/apicregs.hh" #include "arch/x86/segmentregs.hh" #include "arch/x86/x86_traits.hh" #include "base/bitunion.hh" @@ -368,39 +369,9 @@ namespace X86ISA MISCREG_APIC_BASE, + // Space for the APIC registers MISCREG_APIC_START, - MISCREG_APIC_ID = MISCREG_APIC_START, - MISCREG_APIC_VERSION, - MISCREG_APIC_TASK_PRIORITY, - MISCREG_APIC_ARBITRATION_PRIORITY, - MISCREG_APIC_PROCESSOR_PRIORITY, - MISCREG_APIC_EOI, - MISCREG_APIC_LOGICAL_DESTINATION, - MISCREG_APIC_DESTINATION_FORMAT, - MISCREG_APIC_SPURIOUS_INTERRUPT_VECTOR, - - MISCREG_APIC_IN_SERVICE_BASE, - - MISCREG_APIC_TRIGGER_MODE_BASE = MISCREG_APIC_IN_SERVICE_BASE + 16, - - MISCREG_APIC_INTERRUPT_REQUEST_BASE = - MISCREG_APIC_TRIGGER_MODE_BASE + 16, - - MISCREG_APIC_ERROR_STATUS = MISCREG_APIC_INTERRUPT_REQUEST_BASE + 16, - MISCREG_APIC_INTERRUPT_COMMAND_LOW, - MISCREG_APIC_INTERRUPT_COMMAND_HIGH, - MISCREG_APIC_LVT_TIMER, - MISCREG_APIC_LVT_THERMAL_SENSOR, - MISCREG_APIC_LVT_PERFORMANCE_MONITORING_COUNTERS, - MISCREG_APIC_LVT_LINT0, - MISCREG_APIC_LVT_LINT1, - MISCREG_APIC_LVT_ERROR, - MISCREG_APIC_INITIAL_COUNT, - MISCREG_APIC_CURRENT_COUNT, - MISCREG_APIC_DIVIDE_CONFIGURATION, - MISCREG_APIC_END = MISCREG_APIC_DIVIDE_CONFIGURATION, - - MISCREG_APIC_INTERNAL_STATE, + MISCREG_APIC_END = MISCREG_APIC_START + NUM_APIC_REGS - 1, // "Fake" MSRs for internally implemented devices MISCREG_PCI_CONFIG_ADDRESS, @@ -408,6 +379,12 @@ namespace X86ISA NUM_MISCREGS }; + static inline bool + isApicReg(MiscRegIndex index) + { + return index >= MISCREG_APIC_START && index <= MISCREG_APIC_END; + } + static inline MiscRegIndex MISCREG_CR(int index) { @@ -510,24 +487,6 @@ namespace X86ISA return (MiscRegIndex)(MISCREG_SEG_ATTR_BASE + index); } - static inline MiscRegIndex - MISCREG_APIC_IN_SERVICE(int index) - { - return (MiscRegIndex)(MISCREG_APIC_IN_SERVICE_BASE + index); - } - - static inline MiscRegIndex - MISCREG_APIC_TRIGGER_MODE(int index) - { - return (MiscRegIndex)(MISCREG_APIC_TRIGGER_MODE_BASE + index); - } - - static inline MiscRegIndex - MISCREG_APIC_INTERRUPT_REQUEST(int index) - { - return (MiscRegIndex)(MISCREG_APIC_INTERRUPT_REQUEST_BASE + index); - } - /** * A type to describe the condition code bits of the RFLAGS register, * plus two flags, EZF and ECF, which are only visible to microcode. diff --git a/src/arch/x86/mmaped_ipr.hh b/src/arch/x86/mmaped_ipr.hh index cf3eba5e9..67a0b239e 100644 --- a/src/arch/x86/mmaped_ipr.hh +++ b/src/arch/x86/mmaped_ipr.hh @@ -96,7 +96,12 @@ namespace X86ISA #else Addr offset = pkt->getAddr() & mask(3); MiscRegIndex index = (MiscRegIndex)(pkt->getAddr() / sizeof(MiscReg)); - MiscReg data = htog(xc->readMiscRegNoEffect(index)); + MiscReg data; + if (isApicReg(index)) { + data = htog(xc->readMiscReg(index)); + } else { + data = htog(xc->readMiscRegNoEffect(index)); + } // Make sure we don't trot off the end of data. assert(offset + pkt->getSize() <= sizeof(MiscReg)); pkt->writeData(((uint8_t *)&data) + offset); diff --git a/src/arch/x86/regfile.cc b/src/arch/x86/regfile.cc index c8ec2a957..78fde7474 100644 --- a/src/arch/x86/regfile.cc +++ b/src/arch/x86/regfile.cc @@ -135,23 +135,23 @@ void RegFile::clear() MiscReg RegFile::readMiscRegNoEffect(int miscReg) { - return miscRegFile.readRegNoEffect(miscReg); + return miscRegFile.readRegNoEffect((MiscRegIndex)miscReg); } MiscReg RegFile::readMiscReg(int miscReg, ThreadContext *tc) { - return miscRegFile.readReg(miscReg, tc); + return miscRegFile.readReg((MiscRegIndex)miscReg, tc); } void RegFile::setMiscRegNoEffect(int miscReg, const MiscReg &val) { - miscRegFile.setRegNoEffect(miscReg, val); + miscRegFile.setRegNoEffect((MiscRegIndex)miscReg, val); } void RegFile::setMiscReg(int miscReg, const MiscReg &val, ThreadContext * tc) { - miscRegFile.setReg(miscReg, val, tc); + miscRegFile.setReg((MiscRegIndex)miscReg, val, tc); } FloatReg RegFile::readFloatReg(int floatReg, int width) diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 692d6d022..616f026cf 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -663,31 +663,31 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) switch (paddr - baseAddr) { case 0x20: - regNum = MISCREG_APIC_ID; + regNum = APIC_ID; break; case 0x30: - regNum = MISCREG_APIC_VERSION; + regNum = APIC_VERSION; break; case 0x80: - regNum = MISCREG_APIC_TASK_PRIORITY; + regNum = APIC_TASK_PRIORITY; break; case 0x90: - regNum = MISCREG_APIC_ARBITRATION_PRIORITY; + regNum = APIC_ARBITRATION_PRIORITY; break; case 0xA0: - regNum = MISCREG_APIC_PROCESSOR_PRIORITY; + regNum = APIC_PROCESSOR_PRIORITY; break; case 0xB0: - regNum = MISCREG_APIC_EOI; + regNum = APIC_EOI; break; case 0xD0: - regNum = MISCREG_APIC_LOGICAL_DESTINATION; + regNum = APIC_LOGICAL_DESTINATION; break; case 0xE0: - regNum = MISCREG_APIC_DESTINATION_FORMAT; + regNum = APIC_DESTINATION_FORMAT; break; case 0xF0: - regNum = MISCREG_APIC_SPURIOUS_INTERRUPT_VECTOR; + regNum = APIC_SPURIOUS_INTERRUPT_VECTOR; break; case 0x100: case 0x108: @@ -705,8 +705,7 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) case 0x168: case 0x170: case 0x178: - regNum = MISCREG_APIC_IN_SERVICE( - (paddr - baseAddr - 0x100) / 0x8); + regNum = APIC_IN_SERVICE((paddr - baseAddr - 0x100) / 0x8); break; case 0x180: case 0x188: @@ -724,8 +723,7 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) case 0x1E8: case 0x1F0: case 0x1F8: - regNum = MISCREG_APIC_TRIGGER_MODE( - (paddr - baseAddr - 0x180) / 0x8); + regNum = APIC_TRIGGER_MODE((paddr - baseAddr - 0x180) / 0x8); break; case 0x200: case 0x208: @@ -743,50 +741,50 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) case 0x268: case 0x270: case 0x278: - regNum = MISCREG_APIC_INTERRUPT_REQUEST( - (paddr - baseAddr - 0x200) / 0x8); + regNum = APIC_INTERRUPT_REQUEST((paddr - baseAddr - 0x200) / 0x8); break; case 0x280: - regNum = MISCREG_APIC_ERROR_STATUS; + regNum = APIC_ERROR_STATUS; break; case 0x300: - regNum = MISCREG_APIC_INTERRUPT_COMMAND_LOW; + regNum = APIC_INTERRUPT_COMMAND_LOW; break; case 0x310: - regNum = MISCREG_APIC_INTERRUPT_COMMAND_HIGH; + regNum = APIC_INTERRUPT_COMMAND_HIGH; break; case 0x320: - regNum = MISCREG_APIC_LVT_TIMER; + regNum = APIC_LVT_TIMER; break; case 0x330: - regNum = MISCREG_APIC_LVT_THERMAL_SENSOR; + regNum = APIC_LVT_THERMAL_SENSOR; break; case 0x340: - regNum = MISCREG_APIC_LVT_PERFORMANCE_MONITORING_COUNTERS; + regNum = APIC_LVT_PERFORMANCE_MONITORING_COUNTERS; break; case 0x350: - regNum = MISCREG_APIC_LVT_LINT0; + regNum = APIC_LVT_LINT0; break; case 0x360: - regNum = MISCREG_APIC_LVT_LINT1; + regNum = APIC_LVT_LINT1; break; case 0x370: - regNum = MISCREG_APIC_LVT_ERROR; + regNum = APIC_LVT_ERROR; break; case 0x380: - regNum = MISCREG_APIC_INITIAL_COUNT; + regNum = APIC_INITIAL_COUNT; break; case 0x390: - regNum = MISCREG_APIC_CURRENT_COUNT; + regNum = APIC_CURRENT_COUNT; break; case 0x3E0: - regNum = MISCREG_APIC_DIVIDE_CONFIGURATION; + regNum = APIC_DIVIDE_CONFIGURATION; break; default: // A reserved register field. return new GeneralProtection(0); break; } + regNum += MISCREG_APIC_START; req->setPaddr(regNum * sizeof(MiscReg) + offset); } #endif diff --git a/src/arch/x86/utility.cc b/src/arch/x86/utility.cc index 5fe5bf8c3..852d72a2e 100644 --- a/src/arch/x86/utility.cc +++ b/src/arch/x86/utility.cc @@ -55,11 +55,17 @@ * Authors: Gabe Black */ +#include "config/full_system.hh" + +#if FULL_SYSTEM +#include "arch/x86/interrupts.hh" +#endif #include "arch/x86/intregs.hh" #include "arch/x86/miscregs.hh" #include "arch/x86/segmentregs.hh" #include "arch/x86/utility.hh" #include "arch/x86/x86_traits.hh" +#include "cpu/base.hh" #include "sim/system.hh" namespace X86ISA { @@ -254,9 +260,13 @@ void initCPU(ThreadContext *tc, int cpuId) lApicBase.bsp = (cpuId == 0); tc->setMiscReg(MISCREG_APIC_BASE, lApicBase); - tc->setMiscRegNoEffect(MISCREG_APIC_ID, cpuId << 24); + Interrupts * interrupts = dynamic_cast( + tc->getCpuPtr()->getInterruptController()); + assert(interrupts); + + interrupts->setRegNoEffect(APIC_ID, cpuId << 24); - tc->setMiscRegNoEffect(MISCREG_APIC_VERSION, (5 << 16) | 0x14); + interrupts->setRegNoEffect(APIC_VERSION, (5 << 16) | 0x14); // TODO Set the SMRAM base address (SMBASE) to 0x00030000 -- cgit v1.2.3 From 42ebebf99a7d6ce2358b152f643b52c7946f9202 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 11:08:00 -0700 Subject: X86: Make the local APIC accessible through the memory system directly, and make the timer work. --- src/arch/x86/interrupts.cc | 207 +++++++++++++++++++++++++++++++++++++++----- src/arch/x86/interrupts.hh | 33 +++++-- src/arch/x86/miscregfile.cc | 25 ------ src/arch/x86/miscregs.hh | 11 --- src/arch/x86/mmaped_ipr.hh | 6 +- src/arch/x86/tlb.cc | 141 ++---------------------------- src/arch/x86/utility.cc | 2 + src/arch/x86/x86_traits.hh | 17 +++- 8 files changed, 237 insertions(+), 205 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index 73536f2b4..5814859b3 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -55,10 +55,12 @@ * Authors: Gabe Black */ +#include "arch/x86/apicregs.hh" #include "arch/x86/interrupts.hh" #include "cpu/base.hh" -int divideFromConf(uint32_t conf) +int +divideFromConf(uint32_t conf) { // This figures out what division we want from the division configuration // register in the local APIC. The encoding is a little odd but it can @@ -68,14 +70,171 @@ int divideFromConf(uint32_t conf) return 1 << shift; } -uint32_t -X86ISA::Interrupts::readRegNoEffect(ApicRegIndex reg) +namespace X86ISA { - return regs[reg]; + +ApicRegIndex +decodeAddr(Addr paddr) +{ + ApicRegIndex regNum; + paddr &= ~mask(3); + switch (paddr) + { + case 0x20: + regNum = APIC_ID; + break; + case 0x30: + regNum = APIC_VERSION; + break; + case 0x80: + regNum = APIC_TASK_PRIORITY; + break; + case 0x90: + regNum = APIC_ARBITRATION_PRIORITY; + break; + case 0xA0: + regNum = APIC_PROCESSOR_PRIORITY; + break; + case 0xB0: + regNum = APIC_EOI; + break; + case 0xD0: + regNum = APIC_LOGICAL_DESTINATION; + break; + case 0xE0: + regNum = APIC_DESTINATION_FORMAT; + break; + case 0xF0: + regNum = APIC_SPURIOUS_INTERRUPT_VECTOR; + break; + case 0x100: + case 0x108: + case 0x110: + case 0x118: + case 0x120: + case 0x128: + case 0x130: + case 0x138: + case 0x140: + case 0x148: + case 0x150: + case 0x158: + case 0x160: + case 0x168: + case 0x170: + case 0x178: + regNum = APIC_IN_SERVICE((paddr - 0x100) / 0x8); + break; + case 0x180: + case 0x188: + case 0x190: + case 0x198: + case 0x1A0: + case 0x1A8: + case 0x1B0: + case 0x1B8: + case 0x1C0: + case 0x1C8: + case 0x1D0: + case 0x1D8: + case 0x1E0: + case 0x1E8: + case 0x1F0: + case 0x1F8: + regNum = APIC_TRIGGER_MODE((paddr - 0x180) / 0x8); + break; + case 0x200: + case 0x208: + case 0x210: + case 0x218: + case 0x220: + case 0x228: + case 0x230: + case 0x238: + case 0x240: + case 0x248: + case 0x250: + case 0x258: + case 0x260: + case 0x268: + case 0x270: + case 0x278: + regNum = APIC_INTERRUPT_REQUEST((paddr - 0x200) / 0x8); + break; + case 0x280: + regNum = APIC_ERROR_STATUS; + break; + case 0x300: + regNum = APIC_INTERRUPT_COMMAND_LOW; + break; + case 0x310: + regNum = APIC_INTERRUPT_COMMAND_HIGH; + break; + case 0x320: + regNum = APIC_LVT_TIMER; + break; + case 0x330: + regNum = APIC_LVT_THERMAL_SENSOR; + break; + case 0x340: + regNum = APIC_LVT_PERFORMANCE_MONITORING_COUNTERS; + break; + case 0x350: + regNum = APIC_LVT_LINT0; + break; + case 0x360: + regNum = APIC_LVT_LINT1; + break; + case 0x370: + regNum = APIC_LVT_ERROR; + break; + case 0x380: + regNum = APIC_INITIAL_COUNT; + break; + case 0x390: + regNum = APIC_CURRENT_COUNT; + break; + case 0x3E0: + regNum = APIC_DIVIDE_CONFIGURATION; + break; + default: + // A reserved register field. + panic("Accessed reserved register field %#x.\n", paddr); + break; + } + return regNum; +} +} + +Tick +X86ISA::Interrupts::read(PacketPtr pkt) +{ + Addr offset = pkt->getAddr() - pioAddr; + //Make sure we're at least only accessing one register. + if ((offset & ~mask(3)) != ((offset + pkt->getSize()) & ~mask(3))) + panic("Accessed more than one register at a time in the APIC!\n"); + ApicRegIndex reg = decodeAddr(offset); + uint32_t val = htog(readReg(reg)); + pkt->setData(((uint8_t *)&val) + (offset & mask(3))); + return latency; +} + +Tick +X86ISA::Interrupts::write(PacketPtr pkt) +{ + Addr offset = pkt->getAddr() - pioAddr; + //Make sure we're at least only accessing one register. + if ((offset & ~mask(3)) != ((offset + pkt->getSize()) & ~mask(3))) + panic("Accessed more than one register at a time in the APIC!\n"); + ApicRegIndex reg = decodeAddr(offset); + uint32_t val = regs[reg]; + pkt->writeData(((uint8_t *)&val) + (offset & mask(3))); + setReg(reg, gtoh(val)); + return latency; } uint32_t -X86ISA::Interrupts::readReg(ApicRegIndex reg, ThreadContext * tc) +X86ISA::Interrupts::readReg(ApicRegIndex reg) { if (reg >= APIC_TRIGGER_MODE(0) && reg <= APIC_TRIGGER_MODE(15)) { @@ -104,24 +263,19 @@ X86ISA::Interrupts::readReg(ApicRegIndex reg, ThreadContext * tc) break; case APIC_CURRENT_COUNT: { - uint32_t val = regs[reg] - tc->getCpuPtr()->curCycle(); + assert(clock); + uint32_t val = regs[reg] - curTick / clock; val /= (16 * divideFromConf(regs[APIC_DIVIDE_CONFIGURATION])); return val; } default: break; } - return readRegNoEffect(reg); -} - -void -X86ISA::Interrupts::setRegNoEffect(ApicRegIndex reg, uint32_t val) -{ - regs[reg] = val; + return regs[reg]; } void -X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val, ThreadContext *tc) +X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val) { uint32_t newVal = val; if (reg >= APIC_IN_SERVICE(0) && @@ -201,11 +355,24 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val, ThreadContext *tc) } break; case APIC_INITIAL_COUNT: - newVal = bits(val, 31, 0); - regs[APIC_CURRENT_COUNT] = - tc->getCpuPtr()->curCycle() + - (16 * divideFromConf(regs[APIC_DIVIDE_CONFIGURATION])) * newVal; - //FIXME This should schedule the timer event. + { + assert(clock); + newVal = bits(val, 31, 0); + uint32_t newCount = newVal * + (divideFromConf(regs[APIC_DIVIDE_CONFIGURATION]) * 16); + regs[APIC_CURRENT_COUNT] = newCount + curTick / clock; + // Find out how long a "tick" of the timer should take. + Tick timerTick = 16 * clock; + // Schedule on the edge of the next tick plus the new count. + Tick offset = curTick % timerTick; + if (offset) { + reschedule(apicTimerEvent, + curTick + (newCount + 1) * timerTick - offset, true); + } else { + reschedule(apicTimerEvent, + curTick + newCount * timerTick, true); + } + } break; case APIC_CURRENT_COUNT: //Local APIC Current Count register is read only. @@ -216,7 +383,7 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val, ThreadContext *tc) default: break; } - setRegNoEffect(reg, newVal); + regs[reg] = newVal; return; } diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh index 68bb2e07d..1d5f600bd 100644 --- a/src/arch/x86/interrupts.hh +++ b/src/arch/x86/interrupts.hh @@ -61,6 +61,7 @@ #include "arch/x86/apicregs.hh" #include "arch/x86/faults.hh" #include "cpu/thread_context.hh" +#include "dev/io_device.hh" #include "params/X86LocalApic.hh" #include "sim/eventq.hh" #include "sim/sim_object.hh" @@ -70,10 +71,12 @@ class ThreadContext; namespace X86ISA { -class Interrupts : public SimObject +class Interrupts : public BasicPioDevice { protected: uint32_t regs[NUM_APIC_REGS]; + Tick latency; + Tick clock; class ApicTimerEvent : public Event { @@ -92,20 +95,38 @@ class Interrupts : public SimObject public: typedef X86LocalApicParams Params; + void setClock(Tick newClock) + { + clock = newClock; + } + const Params * params() const { return dynamic_cast(_params); } - uint32_t readRegNoEffect(ApicRegIndex reg); - uint32_t readReg(ApicRegIndex miscReg, ThreadContext *tc); + Tick read(PacketPtr pkt); + Tick write(PacketPtr pkt); + + void addressRanges(AddrRangeList &range_list) + { + range_list.clear(); + range_list.push_back(RangeEx(x86LocalAPICAddress(0, 0), + x86LocalAPICAddress(0, 0) + PageBytes)); + } - void setRegNoEffect(ApicRegIndex reg, uint32_t val); - void setReg(ApicRegIndex reg, uint32_t val, ThreadContext *tc); + uint32_t readReg(ApicRegIndex miscReg); + void setReg(ApicRegIndex reg, uint32_t val); + void setRegNoEffect(ApicRegIndex reg, uint32_t val) + { + regs[reg] = val; + } - Interrupts(Params * p) : SimObject(p) + Interrupts(Params * p) : BasicPioDevice(p), + latency(p->pio_latency), clock(0) { + pioSize = PageBytes; //Set the local apic DFR to the flat model. regs[APIC_DESTINATION_FORMAT] = (uint32_t)(-1); memset(regs, 0, sizeof(regs)); diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc index aba498616..388a83e8d 100644 --- a/src/arch/x86/miscregfile.cc +++ b/src/arch/x86/miscregfile.cc @@ -119,23 +119,11 @@ MiscReg MiscRegFile::readRegNoEffect(MiscRegIndex miscReg) !(miscReg > MISCREG_CR8 && miscReg <= MISCREG_CR15)); - if (isApicReg(miscReg)) { - panic("Can't readRegNoEffect from the local APIC.\n"); - } return regVal[miscReg]; } MiscReg MiscRegFile::readReg(MiscRegIndex miscReg, ThreadContext * tc) { -#if FULL_SYSTEM - if (isApicReg(miscReg)) { - Interrupts * interrupts = dynamic_cast( - tc->getCpuPtr()->getInterruptController()); - assert(interrupts); - return interrupts->readReg( - (ApicRegIndex)(miscReg - MISCREG_APIC_START), tc); - } -#endif if (miscReg == MISCREG_TSC) { return regVal[MISCREG_TSC] + tc->getCpuPtr()->curCycle(); } @@ -152,9 +140,6 @@ void MiscRegFile::setRegNoEffect(MiscRegIndex miscReg, const MiscReg &val) miscReg < MISCREG_CR8) && !(miscReg > MISCREG_CR8 && miscReg <= MISCREG_CR15)); - if (isApicReg(miscReg)) { - panic("Can't setRegNoEffect from the local APIC.\n"); - } regVal[miscReg] = val; } @@ -162,16 +147,6 @@ void MiscRegFile::setReg(MiscRegIndex miscReg, const MiscReg &val, ThreadContext * tc) { MiscReg newVal = val; -#if FULL_SYSTEM - if (isApicReg(miscReg)) { - Interrupts * interrupts = dynamic_cast( - tc->getCpuPtr()->getInterruptController()); - assert(interrupts); - interrupts->setReg( - ApicRegIndex(miscReg - MISCREG_APIC_START), val, tc); - return; - } -#endif switch(miscReg) { case MISCREG_CR0: diff --git a/src/arch/x86/miscregs.hh b/src/arch/x86/miscregs.hh index dbf08ec5d..a536d9e3b 100644 --- a/src/arch/x86/miscregs.hh +++ b/src/arch/x86/miscregs.hh @@ -58,7 +58,6 @@ #ifndef __ARCH_X86_MISCREGS_HH__ #define __ARCH_X86_MISCREGS_HH__ -#include "arch/x86/apicregs.hh" #include "arch/x86/segmentregs.hh" #include "arch/x86/x86_traits.hh" #include "base/bitunion.hh" @@ -369,22 +368,12 @@ namespace X86ISA MISCREG_APIC_BASE, - // Space for the APIC registers - MISCREG_APIC_START, - MISCREG_APIC_END = MISCREG_APIC_START + NUM_APIC_REGS - 1, - // "Fake" MSRs for internally implemented devices MISCREG_PCI_CONFIG_ADDRESS, NUM_MISCREGS }; - static inline bool - isApicReg(MiscRegIndex index) - { - return index >= MISCREG_APIC_START && index <= MISCREG_APIC_END; - } - static inline MiscRegIndex MISCREG_CR(int index) { diff --git a/src/arch/x86/mmaped_ipr.hh b/src/arch/x86/mmaped_ipr.hh index 67a0b239e..7056c0902 100644 --- a/src/arch/x86/mmaped_ipr.hh +++ b/src/arch/x86/mmaped_ipr.hh @@ -97,11 +97,7 @@ namespace X86ISA Addr offset = pkt->getAddr() & mask(3); MiscRegIndex index = (MiscRegIndex)(pkt->getAddr() / sizeof(MiscReg)); MiscReg data; - if (isApicReg(index)) { - data = htog(xc->readMiscReg(index)); - } else { - data = htog(xc->readMiscRegNoEffect(index)); - } + data = htog(xc->readMiscRegNoEffect(index)); // Make sure we don't trot off the end of data. assert(offset + pkt->getSize() <= sizeof(MiscReg)); pkt->writeData(((uint8_t *)&data) + offset); diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 616f026cf..5db678919 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -638,10 +638,9 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) // Check for an access to the local APIC #if FULL_SYSTEM LocalApicBase localApicBase = tc->readMiscRegNoEffect(MISCREG_APIC_BASE); - Addr baseAddr = localApicBase.base << 12; + Addr baseAddr = localApicBase.base * PageBytes; Addr paddr = req->getPaddr(); - if (baseAddr <= paddr && baseAddr + (1 << 12) > paddr) { - req->setMmapedIpr(true); + if (baseAddr <= paddr && baseAddr + PageBytes > paddr) { // The Intel developer's manuals say the below restrictions apply, // but the linux kernel, because of a compiler optimization, breaks // them. @@ -653,139 +652,9 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) if (req->getSize() != (32/8)) return new GeneralProtection(0); */ - - //Make sure we're at least only accessing one register. - if ((paddr & ~mask(3)) != ((paddr + req->getSize()) & ~mask(3))) - panic("Accessed more than one register at a time in the APIC!\n"); - MiscReg regNum; - Addr offset = paddr & mask(3); - paddr &= ~mask(3); - switch (paddr - baseAddr) - { - case 0x20: - regNum = APIC_ID; - break; - case 0x30: - regNum = APIC_VERSION; - break; - case 0x80: - regNum = APIC_TASK_PRIORITY; - break; - case 0x90: - regNum = APIC_ARBITRATION_PRIORITY; - break; - case 0xA0: - regNum = APIC_PROCESSOR_PRIORITY; - break; - case 0xB0: - regNum = APIC_EOI; - break; - case 0xD0: - regNum = APIC_LOGICAL_DESTINATION; - break; - case 0xE0: - regNum = APIC_DESTINATION_FORMAT; - break; - case 0xF0: - regNum = APIC_SPURIOUS_INTERRUPT_VECTOR; - break; - case 0x100: - case 0x108: - case 0x110: - case 0x118: - case 0x120: - case 0x128: - case 0x130: - case 0x138: - case 0x140: - case 0x148: - case 0x150: - case 0x158: - case 0x160: - case 0x168: - case 0x170: - case 0x178: - regNum = APIC_IN_SERVICE((paddr - baseAddr - 0x100) / 0x8); - break; - case 0x180: - case 0x188: - case 0x190: - case 0x198: - case 0x1A0: - case 0x1A8: - case 0x1B0: - case 0x1B8: - case 0x1C0: - case 0x1C8: - case 0x1D0: - case 0x1D8: - case 0x1E0: - case 0x1E8: - case 0x1F0: - case 0x1F8: - regNum = APIC_TRIGGER_MODE((paddr - baseAddr - 0x180) / 0x8); - break; - case 0x200: - case 0x208: - case 0x210: - case 0x218: - case 0x220: - case 0x228: - case 0x230: - case 0x238: - case 0x240: - case 0x248: - case 0x250: - case 0x258: - case 0x260: - case 0x268: - case 0x270: - case 0x278: - regNum = APIC_INTERRUPT_REQUEST((paddr - baseAddr - 0x200) / 0x8); - break; - case 0x280: - regNum = APIC_ERROR_STATUS; - break; - case 0x300: - regNum = APIC_INTERRUPT_COMMAND_LOW; - break; - case 0x310: - regNum = APIC_INTERRUPT_COMMAND_HIGH; - break; - case 0x320: - regNum = APIC_LVT_TIMER; - break; - case 0x330: - regNum = APIC_LVT_THERMAL_SENSOR; - break; - case 0x340: - regNum = APIC_LVT_PERFORMANCE_MONITORING_COUNTERS; - break; - case 0x350: - regNum = APIC_LVT_LINT0; - break; - case 0x360: - regNum = APIC_LVT_LINT1; - break; - case 0x370: - regNum = APIC_LVT_ERROR; - break; - case 0x380: - regNum = APIC_INITIAL_COUNT; - break; - case 0x390: - regNum = APIC_CURRENT_COUNT; - break; - case 0x3E0: - regNum = APIC_DIVIDE_CONFIGURATION; - break; - default: - // A reserved register field. - return new GeneralProtection(0); - break; - } - regNum += MISCREG_APIC_START; - req->setPaddr(regNum * sizeof(MiscReg) + offset); + // Force the access to be uncacheable. + req->setFlags(req->getFlags() | UNCACHEABLE); + req->setPaddr(x86LocalAPICAddress(tc->readCpuId(), paddr - baseAddr)); } #endif return NoFault; diff --git a/src/arch/x86/utility.cc b/src/arch/x86/utility.cc index 852d72a2e..43a5ca1a9 100644 --- a/src/arch/x86/utility.cc +++ b/src/arch/x86/utility.cc @@ -267,6 +267,8 @@ void initCPU(ThreadContext *tc, int cpuId) interrupts->setRegNoEffect(APIC_ID, cpuId << 24); interrupts->setRegNoEffect(APIC_VERSION, (5 << 16) | 0x14); + + interrupts->setClock(tc->getCpuPtr()->ticks(16)); // TODO Set the SMRAM base address (SMBASE) to 0x00030000 diff --git a/src/arch/x86/x86_traits.hh b/src/arch/x86/x86_traits.hh index f46279c81..6b4671a08 100644 --- a/src/arch/x86/x86_traits.hh +++ b/src/arch/x86/x86_traits.hh @@ -55,11 +55,13 @@ * Authors: Gabe Black */ -#include "sim/host.hh" - #ifndef __ARCH_X86_X86TRAITS_HH__ #define __ARCH_X86_X86TRAITS_HH__ +#include + +#include "sim/host.hh" + namespace X86ISA { const int NumMicroIntRegs = 16; @@ -90,6 +92,10 @@ namespace X86ISA const Addr PhysAddrPrefixIO = ULL(0x8000000000000000); const Addr PhysAddrPrefixPciConfig = ULL(0xC000000000000000); + const Addr PhysAddrPrefixLocalAPIC = ULL(0xA000000000000000); + // Each APIC gets two pages. One page is used for local apics to field + // accesses from the CPU, and the other is for all APICs to communicate. + const Addr PhysAddrAPICRangeSize = 1 << 12; static inline Addr x86IOAddress(const uint32_t port) @@ -102,6 +108,13 @@ namespace X86ISA { return PhysAddrPrefixPciConfig | addr; } + + static inline Addr + x86LocalAPICAddress(const uint8_t id, const uint16_t addr) + { + assert(addr < (1 << 12)); + return PhysAddrPrefixLocalAPIC | (id * (1 << 12)) | addr; + } } #endif //__ARCH_X86_X86TRAITS_HH__ -- cgit v1.2.3 From e0f137a87c21eca5faa35cf0b9b529c4243d3ff3 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 12:07:25 -0700 Subject: X86: Add a LocalApic trace flag. --- src/arch/x86/SConscript | 2 ++ src/arch/x86/interrupts.cc | 6 ++++++ 2 files changed, 8 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript index e019b77c9..c1a1b9ba3 100644 --- a/src/arch/x86/SConscript +++ b/src/arch/x86/SConscript @@ -109,6 +109,8 @@ if env['TARGET_ISA'] == 'x86': TraceFlag('X86') if env['FULL_SYSTEM']: + TraceFlag('LocalApic') + SimObject('X86LocalApic.py') SimObject('X86System.py') diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index 5814859b3..6f1920de0 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -215,6 +215,9 @@ X86ISA::Interrupts::read(PacketPtr pkt) panic("Accessed more than one register at a time in the APIC!\n"); ApicRegIndex reg = decodeAddr(offset); uint32_t val = htog(readReg(reg)); + DPRINTF(LocalApic, + "Reading Local APIC register %d at offset %#x as %#x.\n", + reg, offset, val); pkt->setData(((uint8_t *)&val) + (offset & mask(3))); return latency; } @@ -229,6 +232,9 @@ X86ISA::Interrupts::write(PacketPtr pkt) ApicRegIndex reg = decodeAddr(offset); uint32_t val = regs[reg]; pkt->writeData(((uint8_t *)&val) + (offset & mask(3))); + DPRINTF(LocalApic, + "Writing Local APIC register %d at offset %#x as %#x.\n", + reg, offset, gtoh(val)); setReg(reg, gtoh(val)); return latency; } -- cgit v1.2.3 From 557bde43c331024eb5cecf4093a24a5b7a9cc266 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 13:28:54 -0700 Subject: X86: Make APICs communicate through the memory system. --- src/arch/x86/X86LocalApic.py | 1 + src/arch/x86/interrupts.cc | 21 +++++++++++ src/arch/x86/interrupts.hh | 21 +++++++++-- src/arch/x86/intmessage.hh | 84 ++++++++++++++++++++++++++++++++++++++++++++ src/arch/x86/x86_traits.hh | 8 +++++ 5 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 src/arch/x86/intmessage.hh (limited to 'src/arch') diff --git a/src/arch/x86/X86LocalApic.py b/src/arch/x86/X86LocalApic.py index 94e32ae50..483c65ef8 100644 --- a/src/arch/x86/X86LocalApic.py +++ b/src/arch/x86/X86LocalApic.py @@ -33,3 +33,4 @@ class X86LocalApic(BasicPioDevice): type = 'X86LocalApic' cxx_class = 'X86ISA::Interrupts' pio_latency = Param.Latency('1ns', 'Programmed IO latency in simticks') + int_port = Port("Port for sending and receiving interrupt messages") diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index 6f1920de0..5614a37eb 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -239,6 +239,27 @@ X86ISA::Interrupts::write(PacketPtr pkt) return latency; } +Tick +X86ISA::Interrupts::recvMessage(PacketPtr pkt) +{ + Addr offset = pkt->getAddr() - x86InterruptAddress(0, 0); + assert(pkt->cmd == MemCmd::MessageReq); + switch(offset) + { + case 0: + DPRINTF(LocalApic, "Got Trigger Interrupt message.\n"); + break; + default: + panic("Local apic got unknown interrupt message at offset %#x.\n", + offset); + break; + } + delete pkt->req; + delete pkt; + return latency; +} + + uint32_t X86ISA::Interrupts::readReg(ApicRegIndex reg) { diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh index 1d5f600bd..c4760dc0f 100644 --- a/src/arch/x86/interrupts.hh +++ b/src/arch/x86/interrupts.hh @@ -62,16 +62,16 @@ #include "arch/x86/faults.hh" #include "cpu/thread_context.hh" #include "dev/io_device.hh" +#include "dev/x86/intdev.hh" #include "params/X86LocalApic.hh" #include "sim/eventq.hh" -#include "sim/sim_object.hh" class ThreadContext; namespace X86ISA { -class Interrupts : public BasicPioDevice +class Interrupts : public BasicPioDevice, IntDev { protected: uint32_t regs[NUM_APIC_REGS]; @@ -108,6 +108,7 @@ class Interrupts : public BasicPioDevice Tick read(PacketPtr pkt); Tick write(PacketPtr pkt); + Tick recvMessage(PacketPtr pkt); void addressRanges(AddrRangeList &range_list) { @@ -116,6 +117,13 @@ class Interrupts : public BasicPioDevice x86LocalAPICAddress(0, 0) + PageBytes)); } + void getIntAddrRange(AddrRangeList &range_list) + { + range_list.clear(); + range_list.push_back(RangeEx(x86InterruptAddress(0, 0), + x86InterruptAddress(0, 0) + PhysAddrAPICRangeSize)); + } + uint32_t readReg(ApicRegIndex miscReg); void setReg(ApicRegIndex reg, uint32_t val); void setRegNoEffect(ApicRegIndex reg, uint32_t val) @@ -123,7 +131,7 @@ class Interrupts : public BasicPioDevice regs[reg] = val; } - Interrupts(Params * p) : BasicPioDevice(p), + Interrupts(Params * p) : BasicPioDevice(p), IntDev(this), latency(p->pio_latency), clock(0) { pioSize = PageBytes; @@ -133,6 +141,13 @@ class Interrupts : public BasicPioDevice clear_all(); } + Port *getPort(const std::string &if_name, int idx = -1) + { + if (if_name == "int_port") + return intPort; + return BasicPioDevice::getPort(if_name, idx); + } + int InterruptLevel(uint64_t softint) { panic("Interrupts::InterruptLevel unimplemented!\n"); diff --git a/src/arch/x86/intmessage.hh b/src/arch/x86/intmessage.hh new file mode 100644 index 000000000..64e821a41 --- /dev/null +++ b/src/arch/x86/intmessage.hh @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2008 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef __ARCH_X86_INTMESSAGE_HH__ +#define __ARCH_X86_INTMESSAGE_HH__ + +#include "arch/x86/x86_traits.hh" +#include "base/bitunion.hh" +#include "mem/packet.hh" +#include "mem/request.hh" +#include "sim/host.hh" + +namespace X86ISA +{ + BitUnion32(TriggerIntMessage) + Bitfield<7, 0> destination; + Bitfield<15, 8> vector; + Bitfield<18, 16> deliveryMode; + Bitfield<19> destMode; + EndBitUnion(TriggerIntMessage) + + static const Addr TriggerIntOffset = 0; + + static inline PacketPtr + prepIntRequest(const uint8_t id, Addr offset, Addr size) + { + RequestPtr req = new Request(x86InterruptAddress(id, offset), + size, UNCACHEABLE); + PacketPtr pkt = new Packet(req, MemCmd::MessageReq, Packet::Broadcast); + pkt->allocate(); + return pkt; + } + + template + PacketPtr + buildIntRequest(const uint8_t id, T payload, Addr offset, Addr size) + { + PacketPtr pkt = prepIntRequest(id, offset, size); + pkt->set(payload); + return pkt; + } + + static inline PacketPtr + buildIntRequest(const uint8_t id, TriggerIntMessage payload) + { + return buildIntRequest(id, payload, TriggerIntOffset, + sizeof(TriggerIntMessage)); + } + + static inline PacketPtr + buildIntResponse() + { + panic("buildIntResponse not implemented.\n"); + } +} + +#endif diff --git a/src/arch/x86/x86_traits.hh b/src/arch/x86/x86_traits.hh index 6b4671a08..be7572517 100644 --- a/src/arch/x86/x86_traits.hh +++ b/src/arch/x86/x86_traits.hh @@ -93,6 +93,7 @@ namespace X86ISA const Addr PhysAddrPrefixIO = ULL(0x8000000000000000); const Addr PhysAddrPrefixPciConfig = ULL(0xC000000000000000); const Addr PhysAddrPrefixLocalAPIC = ULL(0xA000000000000000); + const Addr PhysAddrPrefixInterrupts = ULL(0x2000000000000000); // Each APIC gets two pages. One page is used for local apics to field // accesses from the CPU, and the other is for all APICs to communicate. const Addr PhysAddrAPICRangeSize = 1 << 12; @@ -115,6 +116,13 @@ namespace X86ISA assert(addr < (1 << 12)); return PhysAddrPrefixLocalAPIC | (id * (1 << 12)) | addr; } + + static inline Addr + x86InterruptAddress(const uint8_t id, const uint16_t addr) + { + assert(addr < PhysAddrAPICRangeSize); + return PhysAddrPrefixInterrupts | (id * PhysAddrAPICRangeSize) | addr; + } } #endif //__ARCH_X86_X86TRAITS_HH__ -- cgit v1.2.3 From 3420ad7644b0f2e5dab9f99dfb4407be78e25305 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 13:29:26 -0700 Subject: X86: Make the bases for x86 fault class public. --- src/arch/x86/faults.hh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/faults.hh b/src/arch/x86/faults.hh index 78a55d0e1..a54bc8ee9 100644 --- a/src/arch/x86/faults.hh +++ b/src/arch/x86/faults.hh @@ -317,7 +317,7 @@ namespace X86ISA {} }; - class AlignmentCheck : X86Fault + class AlignmentCheck : public X86Fault { public: AlignmentCheck() : @@ -325,7 +325,7 @@ namespace X86ISA {} }; - class MachineCheck : X86Abort + class MachineCheck : public X86Abort { public: MachineCheck() : @@ -333,7 +333,7 @@ namespace X86ISA {} }; - class SIMDFloatingPointFault : X86Fault + class SIMDFloatingPointFault : public X86Fault { public: SIMDFloatingPointFault() : @@ -341,7 +341,7 @@ namespace X86ISA {} }; - class SecurityException : X86FaultBase + class SecurityException : public X86FaultBase { public: SecurityException() : @@ -349,7 +349,7 @@ namespace X86ISA {} }; - class ExternalInterrupt : X86Interrupt + class ExternalInterrupt : public X86Interrupt { public: ExternalInterrupt() : @@ -357,7 +357,7 @@ namespace X86ISA {} }; - class SoftwareInterrupt : X86Interrupt + class SoftwareInterrupt : public X86Interrupt { public: SoftwareInterrupt() : -- cgit v1.2.3 From 876f4845f258ed09d348135d8af8cf4a17de1b8a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 13:44:24 -0700 Subject: X86: Make the local APIC handle interrupt messages from the IO APIC. --- src/arch/x86/faults.hh | 5 +- src/arch/x86/interrupts.cc | 67 +++++++++++++++++++++- src/arch/x86/interrupts.hh | 136 +++++++++++++++++++++++++++++++++------------ src/arch/x86/intmessage.hh | 39 +++++++++++++ 4 files changed, 207 insertions(+), 40 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/faults.hh b/src/arch/x86/faults.hh index a54bc8ee9..8fe90299d 100644 --- a/src/arch/x86/faults.hh +++ b/src/arch/x86/faults.hh @@ -351,9 +351,10 @@ namespace X86ISA class ExternalInterrupt : public X86Interrupt { + uint8_t vector; public: - ExternalInterrupt() : - X86Interrupt("External Interrupt", "#INTR") + ExternalInterrupt(uint8_t _vector) : + X86Interrupt("External Interrupt", "#INTR"), vector(_vector) {} }; diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index 5614a37eb..a7c238ace 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -57,7 +57,9 @@ #include "arch/x86/apicregs.hh" #include "arch/x86/interrupts.hh" +#include "arch/x86/intmessage.hh" #include "cpu/base.hh" +#include "mem/packet_access.hh" int divideFromConf(uint32_t conf) @@ -242,12 +244,43 @@ X86ISA::Interrupts::write(PacketPtr pkt) Tick X86ISA::Interrupts::recvMessage(PacketPtr pkt) { - Addr offset = pkt->getAddr() - x86InterruptAddress(0, 0); + uint8_t id = 0; + Addr offset = pkt->getAddr() - x86InterruptAddress(id, 0); assert(pkt->cmd == MemCmd::MessageReq); switch(offset) { case 0: - DPRINTF(LocalApic, "Got Trigger Interrupt message.\n"); + { + TriggerIntMessage message = pkt->get(); + uint8_t vector = message.vector; + DPRINTF(LocalApic, + "Got Trigger Interrupt message with vector %#x.\n", + vector); + // Make sure we're really supposed to get this. + assert((message.destMode == 0 && message.destination == id) || + (bits((int)message.destination, id))); + if (DeliveryMode::isUnmaskable(message.deliveryMode)) { + DPRINTF(LocalApic, "Interrupt is an %s and unmaskable.\n", + DeliveryMode::names[message.deliveryMode]); + panic("Unmaskable interrupts aren't implemented.\n"); + } else if (DeliveryMode::isMaskable(message.deliveryMode)) { + DPRINTF(LocalApic, "Interrupt is an %s and maskable.\n", + DeliveryMode::names[message.deliveryMode]); + // Queue up the interrupt in the IRR. + if (vector > IRRV) + IRRV = vector; + if (!getRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, vector)) { + setRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, vector); + if (message.trigger) { + // Level triggered. + setRegArrayBit(APIC_TRIGGER_MODE_BASE, vector); + } else { + // Edge triggered. + clearRegArrayBit(APIC_TRIGGER_MODE_BASE, vector); + } + } + } + } break; default: panic("Local apic got unknown interrupt message at offset %#x.\n", @@ -414,6 +447,36 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val) return; } +bool +X86ISA::Interrupts::check_interrupts(ThreadContext * tc) const +{ + RFLAGS rflags = tc->readMiscRegNoEffect(MISCREG_RFLAGS); + if (IRRV > ISRV && rflags.intf && + bits(IRRV, 7, 4) > bits(regs[APIC_TASK_PRIORITY], 7, 4)) { + return true; + } + return false; +} + +Fault +X86ISA::Interrupts::getInterrupt(ThreadContext * tc) +{ + assert(check_interrupts(tc)); + return new ExternalInterrupt(IRRV); +} + +void +X86ISA::Interrupts::updateIntrInfo(ThreadContext * tc) +{ + assert(check_interrupts(tc)); + // Mark the interrupt as "in service". + ISRV = IRRV; + setRegArrayBit(APIC_IN_SERVICE_BASE, ISRV); + // Clear it out of the IRR. + clearRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, IRRV); + updateIRRV(); +} + X86ISA::Interrupts * X86LocalApicParams::create() { diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh index c4760dc0f..cfc1ada9d 100644 --- a/src/arch/x86/interrupts.hh +++ b/src/arch/x86/interrupts.hh @@ -60,6 +60,7 @@ #include "arch/x86/apicregs.hh" #include "arch/x86/faults.hh" +#include "base/bitfield.hh" #include "cpu/thread_context.hh" #include "dev/io_device.hh" #include "dev/x86/intdev.hh" @@ -74,7 +75,12 @@ namespace X86ISA class Interrupts : public BasicPioDevice, IntDev { protected: + // Storage for the APIC registers uint32_t regs[NUM_APIC_REGS]; + + /* + * Timing related stuff. + */ Tick latency; Tick clock; @@ -92,7 +98,58 @@ class Interrupts : public BasicPioDevice, IntDev ApicTimerEvent apicTimerEvent; + /* + * IRR and ISR maintenance. + */ + uint8_t IRRV; + uint8_t ISRV; + + int + findRegArrayMSB(ApicRegIndex base) + { + int offset = 7; + do { + if (regs[base + offset] != 0) { + return offset * 32 + findMsbSet(regs[base + offset]); + } + } while (offset--); + return 0; + } + + void + updateIRRV() + { + IRRV = findRegArrayMSB(APIC_INTERRUPT_REQUEST_BASE); + } + + void + updateISRV() + { + ISRV = findRegArrayMSB(APIC_IN_SERVICE_BASE); + } + + void + setRegArrayBit(ApicRegIndex base, uint8_t vector) + { + regs[base + (vector % 32)] |= (1 << (vector >> 5)); + } + + void + clearRegArrayBit(ApicRegIndex base, uint8_t vector) + { + regs[base + (vector % 32)] &= ~(1 << (vector >> 5)); + } + + bool + getRegArrayBit(ApicRegIndex base, uint8_t vector) + { + return bits(regs[base + (vector % 32)], vector >> 5); + } + public: + /* + * Params stuff. + */ typedef X86LocalApicParams Params; void setClock(Tick newClock) @@ -106,6 +163,9 @@ class Interrupts : public BasicPioDevice, IntDev return dynamic_cast(_params); } + /* + * Functions to interact with the interrupt port from IntDev. + */ Tick read(PacketPtr pkt); Tick write(PacketPtr pkt); Tick recvMessage(PacketPtr pkt); @@ -124,6 +184,17 @@ class Interrupts : public BasicPioDevice, IntDev x86InterruptAddress(0, 0) + PhysAddrAPICRangeSize)); } + Port *getPort(const std::string &if_name, int idx = -1) + { + if (if_name == "int_port") + return intPort; + return BasicPioDevice::getPort(if_name, idx); + } + + /* + * Functions to access and manipulate the APIC's registers. + */ + uint32_t readReg(ApicRegIndex miscReg); void setReg(ApicRegIndex reg, uint32_t val); void setRegNoEffect(ApicRegIndex reg, uint32_t val) @@ -131,29 +202,47 @@ class Interrupts : public BasicPioDevice, IntDev regs[reg] = val; } + /* + * Constructor. + */ + Interrupts(Params * p) : BasicPioDevice(p), IntDev(this), latency(p->pio_latency), clock(0) { pioSize = PageBytes; + memset(regs, 0, sizeof(regs)); //Set the local apic DFR to the flat model. regs[APIC_DESTINATION_FORMAT] = (uint32_t)(-1); - memset(regs, 0, sizeof(regs)); - clear_all(); + ISRV = 0; + IRRV = 0; } - Port *getPort(const std::string &if_name, int idx = -1) + /* + * Functions for retrieving interrupts for the CPU to handle. + */ + + bool check_interrupts(ThreadContext * tc) const; + Fault getInterrupt(ThreadContext * tc); + void updateIntrInfo(ThreadContext * tc); + + /* + * Serialization. + */ + + void serialize(std::ostream & os) { - if (if_name == "int_port") - return intPort; - return BasicPioDevice::getPort(if_name, idx); + panic("Interrupts::serialize unimplemented!\n"); } - int InterruptLevel(uint64_t softint) + void unserialize(Checkpoint * cp, const std::string & section) { - panic("Interrupts::InterruptLevel unimplemented!\n"); - return 0; + panic("Interrupts::unserialize unimplemented!\n"); } + /* + * Old functions needed for compatability but which will be phased out + * eventually. + */ void post(int int_num, int index) { panic("Interrupts::post unimplemented!\n"); @@ -161,37 +250,12 @@ class Interrupts : public BasicPioDevice, IntDev void clear(int int_num, int index) { - warn("Interrupts::clear unimplemented!\n"); + panic("Interrupts::clear unimplemented!\n"); } void clear_all() { - warn("Interrupts::clear_all unimplemented!\n"); - } - - bool check_interrupts(ThreadContext * tc) const - { - return false; - } - - Fault getInterrupt(ThreadContext * tc) - { - return NoFault; - } - - void updateIntrInfo(ThreadContext * tc) - { - panic("Interrupts::updateIntrInfo unimplemented!\n"); - } - - void serialize(std::ostream & os) - { - panic("Interrupts::serialize unimplemented!\n"); - } - - void unserialize(Checkpoint * cp, const std::string & section) - { - panic("Interrupts::unserialize unimplemented!\n"); + panic("Interrupts::clear_all unimplemented!\n"); } }; diff --git a/src/arch/x86/intmessage.hh b/src/arch/x86/intmessage.hh index 64e821a41..a018a997b 100644 --- a/src/arch/x86/intmessage.hh +++ b/src/arch/x86/intmessage.hh @@ -44,8 +44,47 @@ namespace X86ISA Bitfield<15, 8> vector; Bitfield<18, 16> deliveryMode; Bitfield<19> destMode; + Bitfield<20> level; + Bitfield<21> trigger; EndBitUnion(TriggerIntMessage) + namespace DeliveryMode + { + enum IntDeliveryMode { + Fixed = 0, + LowestPriority = 1, + SMI = 2, + NMI = 4, + INIT = 5, + ExtInt = 7, + NumModes + }; + + static const char * const names[NumModes] = { + "Fixed", "LowestPriority", "SMI", "Reserved", + "NMI", "INIT", "Reserved", "ExtInt" + }; + + static inline bool + isUnmaskable(int mode) + { + return (mode == SMI || mode == NMI || + mode == INIT || mode == ExtInt); + } + + static inline bool + isMaskable(int mode) + { + return (mode == Fixed || mode == LowestPriority); + } + + static inline bool + isReserved(int mode) + { + return !(isMaskable(mode) || isUnmaskable(mode)); + } + } + static const Addr TriggerIntOffset = 0; static inline PacketPtr -- cgit v1.2.3 From ec9d3aad71ec75b3f7b5ea96dd41f067a9261392 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 13:45:21 -0700 Subject: X86: Make the local APIC process interrupts and send them to the CPU. --- src/arch/x86/faults.hh | 22 ++++++++++- src/arch/x86/interrupts.cc | 93 ++++++++++++++++++++++++++++++++++++++-------- src/arch/x86/interrupts.hh | 24 +++++++++++- src/arch/x86/intmessage.hh | 15 +------- 4 files changed, 121 insertions(+), 33 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/faults.hh b/src/arch/x86/faults.hh index 8fe90299d..b15ad15d1 100644 --- a/src/arch/x86/faults.hh +++ b/src/arch/x86/faults.hh @@ -215,9 +215,10 @@ namespace X86ISA class NonMaskableInterrupt : public X86Interrupt { + uint8_t vector; public: - NonMaskableInterrupt() : - X86Interrupt("Non-Maskable-Interrupt", "#NMI") + NonMaskableInterrupt(uint8_t _vector) : + X86Interrupt("Non Maskable Interrupt", "#NMI"), vector(_vector) {} }; @@ -358,6 +359,23 @@ namespace X86ISA {} }; + class SystemManagementInterrupt : public X86Interrupt + { + public: + SystemManagementInterrupt() : + X86Interrupt("System Management Interrupt", "#SMI") + {} + }; + + class InitInterrupt : public X86Interrupt + { + uint8_t vector; + public: + InitInterrupt(uint8_t _vector) : + X86Interrupt("INIT Interrupt", "#INIT"), vector(_vector) + {} + }; + class SoftwareInterrupt : public X86Interrupt { public: diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index a7c238ace..280fa5dd1 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -259,12 +259,15 @@ X86ISA::Interrupts::recvMessage(PacketPtr pkt) // Make sure we're really supposed to get this. assert((message.destMode == 0 && message.destination == id) || (bits((int)message.destination, id))); - if (DeliveryMode::isUnmaskable(message.deliveryMode)) { - DPRINTF(LocalApic, "Interrupt is an %s and unmaskable.\n", - DeliveryMode::names[message.deliveryMode]); - panic("Unmaskable interrupts aren't implemented.\n"); - } else if (DeliveryMode::isMaskable(message.deliveryMode)) { - DPRINTF(LocalApic, "Interrupt is an %s and maskable.\n", + + /* + * Fixed and lowest-priority delivery mode interrupts are handled + * using the IRR/ISR registers, checking against the TPR, etc. + * The SMI, NMI, ExtInt, INIT, etc interrupts go straight through. + */ + if (message.deliveryMode == DeliveryMode::Fixed || + message.deliveryMode == DeliveryMode::LowestPriority) { + DPRINTF(LocalApic, "Interrupt is an %s.\n", DeliveryMode::names[message.deliveryMode]); // Queue up the interrupt in the IRR. if (vector > IRRV) @@ -279,7 +282,27 @@ X86ISA::Interrupts::recvMessage(PacketPtr pkt) clearRegArrayBit(APIC_TRIGGER_MODE_BASE, vector); } } - } + } else if (!DeliveryMode::isReserved(message.deliveryMode)) { + DPRINTF(LocalApic, "Interrupt is an %s.\n", + DeliveryMode::names[message.deliveryMode]); + if (message.deliveryMode == DeliveryMode::SMI && + !pendingSmi) { + pendingUnmaskableInt = pendingSmi = true; + smiMessage = message; + } else if (message.deliveryMode == DeliveryMode::NMI && + !pendingNmi) { + pendingUnmaskableInt = pendingNmi = true; + nmiMessage = message; + } else if (message.deliveryMode == DeliveryMode::ExtInt && + !pendingExtInt) { + pendingExtInt = true; + extIntMessage = message; + } else if (message.deliveryMode == DeliveryMode::INIT && + !pendingInit) { + pendingUnmaskableInt = pendingInit = true; + initMessage = message; + } + } } break; default: @@ -451,9 +474,14 @@ bool X86ISA::Interrupts::check_interrupts(ThreadContext * tc) const { RFLAGS rflags = tc->readMiscRegNoEffect(MISCREG_RFLAGS); - if (IRRV > ISRV && rflags.intf && - bits(IRRV, 7, 4) > bits(regs[APIC_TASK_PRIORITY], 7, 4)) { + if (pendingUnmaskableInt) return true; + if (rflags.intf) { + if (pendingExtInt) + return true; + if (IRRV > ISRV && bits(IRRV, 7, 4) > + bits(regs[APIC_TASK_PRIORITY], 7, 4)) + return true; } return false; } @@ -462,19 +490,52 @@ Fault X86ISA::Interrupts::getInterrupt(ThreadContext * tc) { assert(check_interrupts(tc)); - return new ExternalInterrupt(IRRV); + // These are all probably fairly uncommon, so we'll make them easier to + // check for. + if (pendingUnmaskableInt) { + if (pendingSmi) { + return new SystemManagementInterrupt(); + } else if (pendingNmi) { + return new NonMaskableInterrupt(nmiMessage.vector); + } else if (pendingInit) { + return new InitInterrupt(initMessage.vector); + } else { + panic("pendingUnmaskableInt set, but no unmaskable " + "ints were pending.\n"); + return NoFault; + } + } else if (pendingExtInt) { + return new ExternalInterrupt(extIntMessage.vector); + } else { + // The only thing left are fixed and lowest priority interrupts. + return new ExternalInterrupt(IRRV); + } } void X86ISA::Interrupts::updateIntrInfo(ThreadContext * tc) { assert(check_interrupts(tc)); - // Mark the interrupt as "in service". - ISRV = IRRV; - setRegArrayBit(APIC_IN_SERVICE_BASE, ISRV); - // Clear it out of the IRR. - clearRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, IRRV); - updateIRRV(); + if (pendingUnmaskableInt) { + if (pendingSmi) { + pendingSmi = false; + } else if (pendingNmi) { + pendingNmi = false; + } else if (pendingInit) { + pendingInit = false; + } + if (!(pendingSmi || pendingNmi || pendingInit)) + pendingUnmaskableInt = false; + } else if (pendingExtInt) { + pendingExtInt = false; + } else { + // Mark the interrupt as "in service". + ISRV = IRRV; + setRegArrayBit(APIC_IN_SERVICE_BASE, ISRV); + // Clear it out of the IRR. + clearRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, IRRV); + updateIRRV(); + } } X86ISA::Interrupts * diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh index cfc1ada9d..85a0f6478 100644 --- a/src/arch/x86/interrupts.hh +++ b/src/arch/x86/interrupts.hh @@ -60,6 +60,7 @@ #include "arch/x86/apicregs.hh" #include "arch/x86/faults.hh" +#include "arch/x86/intmessage.hh" #include "base/bitfield.hh" #include "cpu/thread_context.hh" #include "dev/io_device.hh" @@ -98,6 +99,22 @@ class Interrupts : public BasicPioDevice, IntDev ApicTimerEvent apicTimerEvent; + /* + * A set of variables to keep track of interrupts that don't go through + * the IRR. + */ + bool pendingSmi; + TriggerIntMessage smiMessage; + bool pendingNmi; + TriggerIntMessage nmiMessage; + bool pendingExtInt; + TriggerIntMessage extIntMessage; + bool pendingInit; + TriggerIntMessage initMessage; + + // This is a quick check whether any of the above (except ExtInt) are set. + bool pendingUnmaskableInt; + /* * IRR and ISR maintenance. */ @@ -207,7 +224,12 @@ class Interrupts : public BasicPioDevice, IntDev */ Interrupts(Params * p) : BasicPioDevice(p), IntDev(this), - latency(p->pio_latency), clock(0) + latency(p->pio_latency), clock(0), + pendingSmi(false), smiMessage(0), + pendingNmi(false), nmiMessage(0), + pendingExtInt(false), extIntMessage(0), + pendingInit(false), initMessage(0), + pendingUnmaskableInt(false) { pioSize = PageBytes; memset(regs, 0, sizeof(regs)); diff --git a/src/arch/x86/intmessage.hh b/src/arch/x86/intmessage.hh index a018a997b..6a5b3aa30 100644 --- a/src/arch/x86/intmessage.hh +++ b/src/arch/x86/intmessage.hh @@ -65,23 +65,10 @@ namespace X86ISA "NMI", "INIT", "Reserved", "ExtInt" }; - static inline bool - isUnmaskable(int mode) - { - return (mode == SMI || mode == NMI || - mode == INIT || mode == ExtInt); - } - - static inline bool - isMaskable(int mode) - { - return (mode == Fixed || mode == LowestPriority); - } - static inline bool isReserved(int mode) { - return !(isMaskable(mode) || isUnmaskable(mode)); + return mode == 3 || mode == 6; } } -- cgit v1.2.3 From d0a43ce2b29da1640248a756dcd07f0f28561df0 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 14:01:06 -0700 Subject: X86: Fix the ordering of special physical address ranges. --- src/arch/x86/x86_traits.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/x86_traits.hh b/src/arch/x86/x86_traits.hh index be7572517..0347a7099 100644 --- a/src/arch/x86/x86_traits.hh +++ b/src/arch/x86/x86_traits.hh @@ -92,8 +92,8 @@ namespace X86ISA const Addr PhysAddrPrefixIO = ULL(0x8000000000000000); const Addr PhysAddrPrefixPciConfig = ULL(0xC000000000000000); - const Addr PhysAddrPrefixLocalAPIC = ULL(0xA000000000000000); - const Addr PhysAddrPrefixInterrupts = ULL(0x2000000000000000); + const Addr PhysAddrPrefixLocalAPIC = ULL(0x2000000000000000); + const Addr PhysAddrPrefixInterrupts = ULL(0xA000000000000000); // Each APIC gets two pages. One page is used for local apics to field // accesses from the CPU, and the other is for all APICs to communicate. const Addr PhysAddrAPICRangeSize = 1 << 12; -- cgit v1.2.3 From a76c4b8ca101c0c89659a536da6271d4116850de Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 15:31:28 -0700 Subject: X86: Implement CPUID with a magical function instead of microcode. --- src/arch/x86/SConscript | 2 +- src/arch/x86/cpuid.cc | 160 ++++++++ src/arch/x86/cpuid.hh | 61 ++++ src/arch/x86/isa/decoder/two_byte_opcodes.isa | 11 +- src/arch/x86/isa/formats/cpuid.isa | 110 ++++++ src/arch/x86/isa/formats/formats.isa | 3 + src/arch/x86/isa/includes.isa | 1 + src/arch/x86/isa/insts/general_purpose/__init__.py | 1 - .../insts/general_purpose/processor_information.py | 402 --------------------- src/arch/x86/isa/operands.isa | 5 +- 10 files changed, 349 insertions(+), 407 deletions(-) create mode 100644 src/arch/x86/cpuid.cc create mode 100644 src/arch/x86/cpuid.hh create mode 100644 src/arch/x86/isa/formats/cpuid.isa delete mode 100644 src/arch/x86/isa/insts/general_purpose/processor_information.py (limited to 'src/arch') diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript index c1a1b9ba3..cd2445c7e 100644 --- a/src/arch/x86/SConscript +++ b/src/arch/x86/SConscript @@ -86,6 +86,7 @@ Import('*') if env['TARGET_ISA'] == 'x86': + Source('cpuid.cc') Source('emulenv.cc') Source('floatregfile.cc') Source('faults.cc') @@ -173,7 +174,6 @@ if env['TARGET_ISA'] == 'x86': 'general_purpose/load_segment_registers.py', 'general_purpose/logical.py', 'general_purpose/no_operation.py', - 'general_purpose/processor_information.py', 'general_purpose/rotate_and_shift/__init__.py', 'general_purpose/rotate_and_shift/rotate.py', 'general_purpose/rotate_and_shift/shift.py', diff --git a/src/arch/x86/cpuid.cc b/src/arch/x86/cpuid.cc new file mode 100644 index 000000000..247965df4 --- /dev/null +++ b/src/arch/x86/cpuid.cc @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2008 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#include "arch/x86/cpuid.hh" +#include "base/bitfield.hh" +#include "cpu/thread_context.hh" + +namespace X86ISA { + enum StandardCpuidFunction { + VendorAndLargestStdFunc, + FamilyModelStepping, + NumStandardCpuidFuncs + }; + + enum ExtendedCpuidFunctions { + VendorAndLargestExtFunc, + FamilyModelSteppingBrandFeatures, + NameString1, + NameString2, + NameString3, + L1CacheAndTLB, + L2L3CacheAndL2TLB, + APMInfo, + + /* + * The following are defined by the spec but not yet implemented + */ +/* LongModeAddressSize, + // Function 9 is reserved + SVMInfo = 10, + // Functions 11-24 are reserved + TLB1GBPageInfo = 25, + PerformanceInfo,*/ + + NumExtendedCpuidFuncs + }; + + static const int vendorStringSize = 13; + static const char vendorString[vendorStringSize] = "AuthenticAMD"; + static const int nameStringSize = 48; + static const char nameString[nameStringSize] = "Fake M5 x86_64 CPU"; + + uint64_t + stringToRegister(const char *str) + { + uint64_t reg = 0; + for (int pos = 3; pos >=0; pos--) { + reg <<= 8; + reg |= str[pos]; + } + return reg; + } + + bool + doCpuid(ThreadContext * tc, uint32_t function, CpuidResult &result) + { + uint16_t family = bits(function, 31, 16); + uint16_t funcNum = bits(function, 15, 0); + if (family == 0x8000) { + // The extended functions + switch (funcNum) { + case VendorAndLargestExtFunc: + assert(vendorStringSize >= 12); + result = CpuidResult( + NumExtendedCpuidFuncs - 1, + stringToRegister(vendorString), + stringToRegister(vendorString + 4), + stringToRegister(vendorString + 8)); + break; + case FamilyModelSteppingBrandFeatures: + result = CpuidResult(0x00020f51, 0x00000405, + 0xe3d3fbff, 0x00000001); + break; + case NameString1: + case NameString2: + case NameString3: + { + // Zero fill anything beyond the end of the string. This + // should go away once the string is a vetted parameter. + char cleanName[nameStringSize]; + memset(cleanName, '\0', nameStringSize); + strncpy(cleanName, nameString, nameStringSize); + + int offset = (funcNum - NameString1) * 16; + assert(nameStringSize >= offset + 16); + result = CpuidResult( + stringToRegister(cleanName + offset + 0), + stringToRegister(cleanName + offset + 4), + stringToRegister(cleanName + offset + 8), + stringToRegister(cleanName + offset + 12)); + } + break; + case L1CacheAndTLB: + result = CpuidResult(0xff08ff08, 0xff20ff20, + 0x40020140, 0x40020140); + break; + case L2L3CacheAndL2TLB: + result = CpuidResult(0x00000000, 0x42004200, + 0x00000000, 0x04008140); + break; + case APMInfo: + result = CpuidResult(0x80000018, 0x68747541, + 0x69746e65, 0x444d4163); + break; +/* case LongModeAddressSize: + case SVMInfo: + case TLB1GBPageInfo: + case PerformanceInfo:*/ + default: + return false; + } + } else if(family == 0x0000) { + // The standard functions + switch (funcNum) { + case VendorAndLargestStdFunc: + assert(vendorStringSize >= 12); + result = CpuidResult( + NumStandardCpuidFuncs - 1, + stringToRegister(vendorString), + stringToRegister(vendorString + 4), + stringToRegister(vendorString + 8)); + break; + case FamilyModelStepping: + result = CpuidResult(0x00020f51, 0000000405, + 0xe3d3fbff, 0x00000001); + break; + default: + return false; + } + } + return true; + } +} //namespace X86ISA diff --git a/src/arch/x86/cpuid.hh b/src/arch/x86/cpuid.hh new file mode 100644 index 000000000..5cb4c7972 --- /dev/null +++ b/src/arch/x86/cpuid.hh @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2008 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef __ARCH_X86_CPUID_HH__ +#define __ARCH_X86_CPUID_HH__ + +#include + +class ThreadContext; + +namespace X86ISA +{ + struct CpuidResult + { + uint64_t rax; + uint64_t rbx; + uint64_t rcx; + uint64_t rdx; + + // These are not in alphebetical order on purpose. The order reflects + // how the CPUID orders the registers when it returns results. + CpuidResult(uint64_t _rax, uint64_t _rbx, + uint64_t _rdx, uint64_t _rcx) : + rax(_rax), rbx(_rbx), rcx(_rcx), rdx(_rdx) + {} + + CpuidResult() + {} + }; + + bool doCpuid(ThreadContext * tc, uint32_t function, CpuidResult &result); +} // namespace X86ISA + +#endif diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index 5ada6fd4f..bceb0595e 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -168,7 +168,7 @@ #if FULL_SYSTEM 0x05: syscall(); #else - 0x05: SyscallInst::syscall('xc->syscall(rax)', IsSyscall); + 0x05: SyscallInst::syscall('xc->syscall(Rax)', IsSyscall); #endif 0x06: clts(); //sandpile.org says (AMD) after sysret, so I might want to check @@ -707,7 +707,14 @@ 0x14: decode OPCODE_OP_BOTTOM3 { 0x0: push_fs(); 0x1: pop_fs(); - 0x2: Inst::CPUID(rAd); + 0x2: CPUIDInst::CPUID({{ + CpuidResult result; + success = doCpuid(xc->tcBase(), Rax, result); + Rax = result.rax; + Rbx = result.rbx; + Rcx = result.rcx; + Rdx = result.rdx; + }}); 0x3: Inst::BT(Ev,Gv); 0x4: shld_Ev_Gv_Ib(); 0x5: shld_Ev_Gv_rCl(); diff --git a/src/arch/x86/isa/formats/cpuid.isa b/src/arch/x86/isa/formats/cpuid.isa new file mode 100644 index 000000000..204270556 --- /dev/null +++ b/src/arch/x86/isa/formats/cpuid.isa @@ -0,0 +1,110 @@ +// Copyright (c) 2008 The Hewlett-Packard Development Company +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the +// following conditions are met: +// +// The software must be used only for Non-Commercial Use which means any +// use which is NOT directed to receiving any direct monetary +// compensation for, or commercial advantage from such use. Illustrative +// examples of non-commercial use are academic research, personal study, +// teaching, education and corporate research & development. +// Illustrative examples of commercial use are distributing products for +// commercial advantage and providing services using the software for +// commercial advantage. +// +// If you wish to use this software or functionality therein that may be +// covered by patents for commercial use, please contact: +// Director of Intellectual Property Licensing +// Office of Strategy and Technology +// Hewlett-Packard Company +// 1501 Page Mill Road +// Palo Alto, California 94304 +// +// Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. Redistributions +// in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or +// other materials provided with the distribution. Neither the name of +// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. No right of +// sublicense is granted herewith. Derivatives of the software and +// output created using the software may be prepared, but only for +// Non-Commercial Uses. Derivatives of the software may be shared with +// others provided: (i) the others agree to abide by the list of +// conditions herein which includes the Non-Commercial Use restrictions; +// and (ii) such Derivatives of the software include the above copyright +// notice to acknowledge the contribution from this software where +// applicable, this list of conditions and the disclaimer below. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Gabe Black + +output header {{ + class CPUIDInst : public X86ISA::X86StaticInst + { + public: + static const RegIndex foldOBit = 0; + /// Constructor + CPUIDInst(const char *_mnemonic, ExtMachInst _machInst, + OpClass __opClass) : + X86ISA::X86StaticInst(_mnemonic, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + }; +}}; + +output decoder {{ + std::string CPUIDInst::generateDisassembly(Addr PC, + const SymbolTable *symtab) const + { + std::stringstream response; + + printMnemonic(response, mnemonic); + ccprintf(response, " "); + printReg(response, _srcRegIdx[0], machInst.opSize); + return response.str(); + } +}}; + +def template CPUIDExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + // If the CPUID instruction used a valid function number, this will + // be set to true. Otherwise, the instruction does nothing. + bool success; + %(op_decl)s; + %(op_rd)s; + %(code)s; + if (success) { + %(op_wb)s; + } + return NoFault; + } +}}; + +def format CPUIDInst(code, *opt_flags) {{ + iop = InstObjParams(name, Name, 'CPUIDInst', code, opt_flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = CPUIDExecute.subst(iop) +}}; + diff --git a/src/arch/x86/isa/formats/formats.isa b/src/arch/x86/isa/formats/formats.isa index 6906413c0..81179ab45 100644 --- a/src/arch/x86/isa/formats/formats.isa +++ b/src/arch/x86/isa/formats/formats.isa @@ -85,6 +85,9 @@ //Templates from this format are used later ##include "basic.isa" +//Include a format to generate a CPUID instruction. +##include "cpuid.isa" + //Include the "unknown" format ##include "unknown.isa" diff --git a/src/arch/x86/isa/includes.isa b/src/arch/x86/isa/includes.isa index 6d0fe6d86..926e9185a 100644 --- a/src/arch/x86/isa/includes.isa +++ b/src/arch/x86/isa/includes.isa @@ -145,6 +145,7 @@ output exec {{ #include #include +#include "arch/x86/cpuid.hh" #include "arch/x86/miscregs.hh" #include "arch/x86/tlb.hh" #include "base/bigint.hh" diff --git a/src/arch/x86/isa/insts/general_purpose/__init__.py b/src/arch/x86/isa/insts/general_purpose/__init__.py index 4f77cb233..23f955f08 100644 --- a/src/arch/x86/isa/insts/general_purpose/__init__.py +++ b/src/arch/x86/isa/insts/general_purpose/__init__.py @@ -65,7 +65,6 @@ categories = ["arithmetic", "load_segment_registers", "logical", "no_operation", - "processor_information", "rotate_and_shift", "semaphores", "string", diff --git a/src/arch/x86/isa/insts/general_purpose/processor_information.py b/src/arch/x86/isa/insts/general_purpose/processor_information.py deleted file mode 100644 index 4b73789af..000000000 --- a/src/arch/x86/isa/insts/general_purpose/processor_information.py +++ /dev/null @@ -1,402 +0,0 @@ -# Copyright (c) 2007-2008 The Hewlett-Packard Development Company -# All rights reserved. -# -# Redistribution and use of this software in source and binary forms, -# with or without modification, are permitted provided that the -# following conditions are met: -# -# The software must be used only for Non-Commercial Use which means any -# use which is NOT directed to receiving any direct monetary -# compensation for, or commercial advantage from such use. Illustrative -# examples of non-commercial use are academic research, personal study, -# teaching, education and corporate research & development. -# Illustrative examples of commercial use are distributing products for -# commercial advantage and providing services using the software for -# commercial advantage. -# -# If you wish to use this software or functionality therein that may be -# covered by patents for commercial use, please contact: -# Director of Intellectual Property Licensing -# Office of Strategy and Technology -# Hewlett-Packard Company -# 1501 Page Mill Road -# Palo Alto, California 94304 -# -# Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. Redistributions -# in binary form must reproduce the above copyright notice, this list of -# conditions and the following disclaimer in the documentation and/or -# other materials provided with the distribution. Neither the name of -# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. No right of -# sublicense is granted herewith. Derivatives of the software and -# output created using the software may be prepared, but only for -# Non-Commercial Uses. Derivatives of the software may be shared with -# others provided: (i) the others agree to abide by the list of -# conditions herein which includes the Non-Commercial Use restrictions; -# and (ii) such Derivatives of the software include the above copyright -# notice to acknowledge the contribution from this software where -# applicable, this list of conditions and the disclaimer below. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# Authors: Gabe Black - -microcode = ''' -def macroop CPUID_R { - -# -# Find which type of cpuid function it is by checking bit 31. Also clear that -# bit to form an offset into the functions of that type. -# - limm t1, 0x80000000, dataSize=4 - and t2, t1, rax, flags=(EZF,) - # clear the bit - xor t1, t2, rax - -# -# Do range checking on the offset -# - # If EZF is set, the function is standard and the max is 0x1. - movi t2, t2, 0x1, flags=(CEZF,) - # If EZF is cleared, the function is extended and the max is 0x18. - movi t2, t2, 0x18, flags=(nCEZF,) - subi t0, t1, t2, flags=(ECF,) - # ECF will be set if the offset is too large. - bri t0, label("end"), flags=(nCECF,) - - -# -# Jump to the right portion -# - movi t2, t2, label("standardStart"), flags=(CEZF,) - movi t2, t2, label("extendedStart"), flags=(nCEZF,) - # This gives each function 8 microops to use. It's wasteful because only - # 5 will be needed, but a multiply would be expensive. In the system - # described in the RISC86 patent, the fifth instruction would really be - # the sequencing field on an op quad, so each function would be implemented - # by -exactly- one op quad. Since we're approximating, this should be ok. - slli t1, t1, 3 - br t2, t1 - -############################################################################# -############################################################################# - -# -# Standard functions. -# - -standardStart: - -# 0x00000000 -- Processor Vendor and Largest Standard Function Number - limm rax, 0x00000001, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x00000001 -- Family, Model, Stepping Identifiers - limm rax, 0x00020f51, dataSize=4 - limm rbx, 0x00000405, dataSize=4 - limm rdx, 0xe3d3fbff, dataSize=4 - limm rcx, 0x00000001, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# -# Extended functions. -# - -extendedStart: - -# 0x80000000 -- Processor Vendor and Largest Extended Function Number - limm rax, 0x80000018, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x80000001 -- EAX: AMD Family, Model, Stepping -# EBX: BrandId Identifier -# ECX: Feature Identifiers -# EDX: Feature Identifiers - limm rax, 0x00020f51, dataSize=4 - limm rbx, 0x00000405, dataSize=4 - limm rdx, 0xe3d3fbff, dataSize=4 - limm rcx, 0x00000001, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x80000002 -- Processor Name String Identifier - limm rax, 0x656B6146, dataSize=4 - limm rbx, 0x20354D20, dataSize=4 - limm rcx, 0x5F363878, dataSize=4 - limm rdx, 0x43203436, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x80000003 -- Processor Name String Identifier - limm rax, 0x00005550, dataSize=4 - limm rbx, 0x00000000, dataSize=4 - limm rdx, 0x00000000, dataSize=4 - limm rcx, 0x00000000, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x80000004 -- Processor Name String Identifier - limm rax, 0x00000000, dataSize=4 - limm rbx, 0x00000000, dataSize=4 - limm rdx, 0x00000000, dataSize=4 - limm rcx, 0x00000000, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x80000005 -- L1 Cache and TLB Identifiers - limm rax, 0xff08ff08, dataSize=4 - limm rbx, 0xff20ff20, dataSize=4 - limm rdx, 0x40020140, dataSize=4 - limm rcx, 0x40020140, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x80000006 -- L2/L3 Cache and L2 TLB Identifiers - limm rax, 0x00000000, dataSize=4 - limm rbx, 0x42004200, dataSize=4 - limm rdx, 0x00000000, dataSize=4 - limm rcx, 0x04008140, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x80000007 -- Advanced Power Management Information - # JUNK VALUES - limm rax, 0x80000018, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x80000008 -- Long Mode Address Size Identification - # JUNK VALUES - limm rax, 0x80000018, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x80000009 -- Reserved - # JUNK VALUES - limm rax, 0x80000018, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x8000000A -- SVM Revision and Feature Identification - # JUNK VALUES - limm rax, 0x80000018, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x8000000B -- Reserved - # JUNK VALUES - limm rax, 0x80000018, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x8000000C -- Reserved - # JUNK VALUES - limm rax, 0x80000018, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x8000000D -- Reserved - # JUNK VALUES - limm rax, 0x80000018, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x8000000E -- Reserved - # JUNK VALUES - limm rax, 0x80000018, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x8000000F -- Reserved - # JUNK VALUES - limm rax, 0x80000018, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x80000010 -- Reserved - # JUNK VALUES - limm rax, 0x80000018, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x80000011 -- Reserved - # JUNK VALUES - limm rax, 0x80000018, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x80000012 -- Reserved - # JUNK VALUES - limm rax, 0x80000018, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x80000013 -- Reserved - # JUNK VALUES - limm rax, 0x80000018, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x80000014 -- Reserved - # JUNK VALUES - limm rax, 0x80000018, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x80000015 -- Reserved - # JUNK VALUES - limm rax, 0x80000018, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x80000016 -- Reserved - # JUNK VALUES - limm rax, 0x80000018, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x80000017 -- Reserved - # JUNK VALUES - limm rax, 0x80000018, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -# 0x80000018 -- Reserved - # JUNK VALUES - limm rax, 0x80000018, dataSize=4 - limm rbx, 0x68747541, dataSize=4 - limm rdx, 0x69746e65, dataSize=4 - limm rcx, 0x444d4163, dataSize=4 - bri t0, label("end") - fault "NoFault" - fault "NoFault" - fault "NoFault" - -end: - fault "NoFault" -}; -''' diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index 446580c1b..8bb7c5bb1 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -109,7 +109,10 @@ def operands {{ 'Quotient': ('IntReg', 'uqw', 'INTREG_IMPLICIT(2)', 'IsInteger', 9), 'Remainder': ('IntReg', 'uqw', 'INTREG_IMPLICIT(3)', 'IsInteger', 10), 'Divisor': ('IntReg', 'uqw', 'INTREG_IMPLICIT(4)', 'IsInteger', 11), - 'rax': ('IntReg', 'uqw', '(INTREG_RAX)', 'IsInteger', 12), + 'Rax': ('IntReg', 'uqw', '(INTREG_RAX)', 'IsInteger', 12), + 'Rbx': ('IntReg', 'uqw', '(INTREG_RBX)', 'IsInteger', 13), + 'Rcx': ('IntReg', 'uqw', '(INTREG_RCX)', 'IsInteger', 14), + 'Rdx': ('IntReg', 'uqw', '(INTREG_RDX)', 'IsInteger', 15), 'FpSrcReg1': ('FloatReg', 'df', 'src1', 'IsFloating', 20), 'FpSrcReg2': ('FloatReg', 'df', 'src2', 'IsFloating', 21), 'FpDestReg': ('FloatReg', 'df', 'dest', 'IsFloating', 22), -- cgit v1.2.3 From 77c0e1d1102af4c023bcd4609022b1600cadfea5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 15:33:17 -0700 Subject: X86: Create a SeqOp class of microops and make Br one of them. --- .../arithmetic/multiply_and_divide.py | 24 +-- .../general_purpose/compare_and_test/bit_scan.py | 12 +- .../control_transfer/interrupts_and_exceptions.py | 28 +-- .../general_purpose/control_transfer/xreturn.py | 8 +- .../insts/general_purpose/data_transfer/move.py | 36 ++-- .../data_transfer/stack_operations.py | 6 +- .../general_purpose/input_output/string_io.py | 8 +- .../general_purpose/string/compare_strings.py | 8 +- .../insts/general_purpose/string/load_string.py | 4 +- .../insts/general_purpose/string/move_string.py | 4 +- .../insts/general_purpose/string/scan_string.py | 8 +- .../insts/general_purpose/string/store_string.py | 4 +- src/arch/x86/isa/microops/microops.isa | 3 + src/arch/x86/isa/microops/regop.isa | 4 - src/arch/x86/isa/microops/seqop.isa | 208 +++++++++++++++++++++ 15 files changed, 286 insertions(+), 79 deletions(-) create mode 100644 src/arch/x86/isa/microops/seqop.isa (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/arithmetic/multiply_and_divide.py b/src/arch/x86/isa/insts/general_purpose/arithmetic/multiply_and_divide.py index a9b53acac..19d1c7789 100644 --- a/src/arch/x86/isa/insts/general_purpose/arithmetic/multiply_and_divide.py +++ b/src/arch/x86/isa/insts/general_purpose/arithmetic/multiply_and_divide.py @@ -246,7 +246,7 @@ def macroop DIV_B_R divLoopTop: div2 t1, rax, t1, dataSize=1 div2 t1, rax, t1, flags=(EZF,), dataSize=1 - bri t0, label("divLoopTop"), flags=(nCEZF,) + br label("divLoopTop"), flags=(nCEZF,) #Unload the answer divq rax, dataSize=1 @@ -269,7 +269,7 @@ def macroop DIV_B_M divLoopTop: div2 t1, rax, t1, dataSize=1 div2 t1, rax, t1, flags=(EZF,), dataSize=1 - bri t0, label("divLoopTop"), flags=(nCEZF,) + br label("divLoopTop"), flags=(nCEZF,) #Unload the answer divq rax, dataSize=1 @@ -293,7 +293,7 @@ def macroop DIV_B_P divLoopTop: div2 t1, rax, t1, dataSize=1 div2 t1, rax, t1, flags=(EZF,), dataSize=1 - bri t0, label("divLoopTop"), flags=(nCEZF,) + br label("divLoopTop"), flags=(nCEZF,) #Unload the answer divq rax, dataSize=1 @@ -321,7 +321,7 @@ divLoopTop: div2 t1, rax, t1 div2 t1, rax, t1 div2 t1, rax, t1, flags=(EZF,) - bri t0, label("divLoopTop"), flags=(nCEZF,) + br label("divLoopTop"), flags=(nCEZF,) #Unload the answer divq rax @@ -347,7 +347,7 @@ divLoopTop: div2 t1, rax, t1 div2 t1, rax, t1 div2 t1, rax, t1, flags=(EZF,) - bri t0, label("divLoopTop"), flags=(nCEZF,) + br label("divLoopTop"), flags=(nCEZF,) #Unload the answer divq rax @@ -374,7 +374,7 @@ divLoopTop: div2 t1, rax, t1 div2 t1, rax, t1 div2 t1, rax, t1, flags=(EZF,) - bri t0, label("divLoopTop"), flags=(nCEZF,) + br label("divLoopTop"), flags=(nCEZF,) #Unload the answer divq rax @@ -422,7 +422,7 @@ def macroop IDIV_B_R divLoopTop: div2 t4, t1, t4, dataSize=1 div2 t4, t1, t4, flags=(EZF,), dataSize=1 - bri t0, label("divLoopTop"), flags=(nCEZF,) + br label("divLoopTop"), flags=(nCEZF,) #Unload the answer divq t5, dataSize=1 @@ -495,7 +495,7 @@ def macroop IDIV_B_M divLoopTop: div2 t4, t1, t4, dataSize=1 div2 t4, t1, t4, flags=(EZF,), dataSize=1 - bri t0, label("divLoopTop"), flags=(nCEZF,) + br label("divLoopTop"), flags=(nCEZF,) #Unload the answer divq t5, dataSize=1 @@ -569,7 +569,7 @@ def macroop IDIV_B_P divLoopTop: div2 t4, t1, t4, dataSize=1 div2 t4, t1, t4, flags=(EZF,), dataSize=1 - bri t0, label("divLoopTop"), flags=(nCEZF,) + br label("divLoopTop"), flags=(nCEZF,) #Unload the answer divq t5, dataSize=1 @@ -646,7 +646,7 @@ divLoopTop: div2 t4, t1, t4 div2 t4, t1, t4 div2 t4, t1, t4, flags=(EZF,) - bri t0, label("divLoopTop"), flags=(nCEZF,) + br label("divLoopTop"), flags=(nCEZF,) #Unload the answer divq t5 @@ -721,7 +721,7 @@ divLoopTop: div2 t4, t1, t4 div2 t4, t1, t4 div2 t4, t1, t4, flags=(EZF,) - bri t0, label("divLoopTop"), flags=(nCEZF,) + br label("divLoopTop"), flags=(nCEZF,) #Unload the answer divq t5 @@ -797,7 +797,7 @@ divLoopTop: div2 t4, t1, t4 div2 t4, t1, t4 div2 t4, t1, t4, flags=(EZF,) - bri t0, label("divLoopTop"), flags=(nCEZF,) + br label("divLoopTop"), flags=(nCEZF,) #Unload the answer divq t5 diff --git a/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py b/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py index bfc0af900..22364e038 100644 --- a/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py +++ b/src/arch/x86/isa/insts/general_purpose/compare_and_test/bit_scan.py @@ -86,7 +86,7 @@ def macroop BSR_R_R { # Determine if the input was zero, and also move it to a temp reg. movi t1, t1, t0, dataSize=8 and t1, regm, regm, flags=(ZF,) - bri t0, label("end"), flags=(CZF,) + br label("end"), flags=(CZF,) # Zero out the result register movi reg, reg, 0x0 @@ -137,7 +137,7 @@ def macroop BSR_R_M { # Determine if the input was zero, and also move it to a temp reg. and t1, t1, t1, flags=(ZF,) - bri t0, label("end"), flags=(CZF,) + br label("end"), flags=(CZF,) # Zero out the result register movi reg, reg, 0x0 @@ -189,7 +189,7 @@ def macroop BSR_R_P { # Determine if the input was zero, and also move it to a temp reg. and t1, t1, t1, flags=(ZF,) - bri t0, label("end"), flags=(CZF,) + br label("end"), flags=(CZF,) # Zero out the result register movi reg, reg, 0x0 @@ -237,7 +237,7 @@ def macroop BSF_R_R { # Determine if the input was zero, and also move it to a temp reg. mov t1, t1, t0, dataSize=8 and t1, regm, regm, flags=(ZF,) - bri t0, label("end"), flags=(CZF,) + br label("end"), flags=(CZF,) # Zero out the result register movi reg, reg, 0 @@ -292,7 +292,7 @@ def macroop BSF_R_M { # Determine if the input was zero, and also move it to a temp reg. and t1, t1, t1, flags=(ZF,) - bri t0, label("end"), flags=(CZF,) + br label("end"), flags=(CZF,) # Zero out the result register mov reg, reg, t0 @@ -348,7 +348,7 @@ def macroop BSF_R_P { # Determine if the input was zero, and also move it to a temp reg. and t1, t1, t1, flags=(ZF,) - bri t0, label("end"), flags=(CZF,) + br label("end"), flags=(CZF,) # Zero out the result register mov reg, reg, t0 diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py index be562b424..125866ce5 100644 --- a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py +++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py @@ -86,16 +86,16 @@ def macroop IRET_PROT { #temp_RFLAGS.VM != 1 rcri t0, t3, 18, flags=(ECF,) - bri t0, label("protToVirtFallThrough"), flags=(nCECF,) + br label("protToVirtFallThrough"), flags=(nCECF,) #CPL=0 rdm5reg t4 andi t0, t4, 0x30, flags=(EZF,) - bri t0, label("protToVirtFallThrough"), flags=(nCEZF,) + br label("protToVirtFallThrough"), flags=(nCEZF,) #(LEGACY_MODE) rcri t0, t4, 1, flags=(ECF,) - bri t0, label("protToVirtFallThrough"), flags=(nCECF,) + br label("protToVirtFallThrough"), flags=(nCECF,) panic "iret to virtual mode not supported" @@ -113,12 +113,12 @@ protToVirtFallThrough: #CS = READ_DESCRIPTOR (temp_CS, iret_chk) andi t0, t2, 0xFC, flags=(EZF,), dataSize=2 - bri t0, label("processCSDescriptor"), flags=(CEZF,) + br label("processCSDescriptor"), flags=(CEZF,) andi t6, t2, 0xF8, dataSize=8 andi t0, t2, 0x4, flags=(EZF,), dataSize=2 - bri t0, label("globalCSDescriptor"), flags=(CEZF,) + br label("globalCSDescriptor"), flags=(CEZF,) ld t6, tsl, [1, t0, t6], dataSize=8 - bri t0, label("processCSDescriptor") + br label("processCSDescriptor") globalCSDescriptor: ld t6, tsg, [1, t0, t6], dataSize=8 processCSDescriptor: @@ -143,7 +143,7 @@ processCSDescriptor: andi t0, t4, 0xE, flags=(EZF,) # Since we just found out we're in 64 bit mode, take advantage and # do the appropriate RIP checks. - bri t0, label("doPopStackStuffAndCheckRIP"), flags=(CEZF,) + br label("doPopStackStuffAndCheckRIP"), flags=(CEZF,) # Here, we know we're -not- in 64 bit mode, so we should do the # appropriate/other RIP checks. @@ -156,17 +156,17 @@ processCSDescriptor: srli t7, t4, 4 xor t7, t7, t5 andi t0, t7, 0x3, flags=(EZF,) - bri t0, label("doPopStackStuff"), flags=(nCEZF,) + br label("doPopStackStuff"), flags=(nCEZF,) # We can modify user visible state here because we're know # we're done with things that can fault. addi rsp, rsp, "3 * env.stackSize" - bri t0, label("fallThroughPopStackStuff") + br label("fallThroughPopStackStuff") doPopStackStuffAndCheckRIP: # Check if the RIP is canonical. sra t7, t1, 47, flags=(EZF,), dataSize=ssz # if t7 isn't 0 or -1, it wasn't canonical. - bri t0, label("doPopStackStuff"), flags=(CEZF,) + br label("doPopStackStuff"), flags=(CEZF,) addi t0, t7, 1, flags=(EZF,), dataSize=ssz fault "new GeneralProtection(0)", flags=(nCEZF,) @@ -177,12 +177,12 @@ doPopStackStuff: ld t2, ss, [1, t0, rsp], "4 * env.dataSize", dataSize=ssz # SS = READ_DESCRIPTOR (temp_SS, ss_chk) andi t0, t2, 0xFC, flags=(EZF,), dataSize=2 - bri t0, label("processSSDescriptor"), flags=(CEZF,) + br label("processSSDescriptor"), flags=(CEZF,) andi t7, t2, 0xF8, dataSize=8 andi t0, t2, 0x4, flags=(EZF,), dataSize=2 - bri t0, label("globalSSDescriptor"), flags=(CEZF,) + br label("globalSSDescriptor"), flags=(CEZF,) ld t7, tsl, [1, t0, t7], dataSize=8 - bri t0, label("processSSDescriptor") + br label("processSSDescriptor") globalSSDescriptor: ld t7, tsg, [1, t0, t7], dataSize=8 processSSDescriptor: @@ -208,7 +208,7 @@ fallThroughPopStackStuff: srli t7, t4, 4 xor t7, t7, t5 andi t0, t7, 0x3, flags=(EZF,) - bri t0, label("skipSegmentSquashing"), flags=(CEZF,) + br label("skipSegmentSquashing"), flags=(CEZF,) # The attribute register needs to keep track of more info before this will # work the way it needs to. diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py index d1a8245e6..57ec9da26 100644 --- a/src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py +++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/xreturn.py @@ -97,12 +97,12 @@ def macroop RET_FAR { # Do stuff if they're equal andi t0, t2, 0xFC, flags=(EZF,), dataSize=2 - bri t0, label("processDescriptor"), flags=(CEZF,) + br label("processDescriptor"), flags=(CEZF,) andi t3, t2, 0xF8, dataSize=8 andi t0, t2, 0x4, flags=(EZF,), dataSize=2 - bri t0, label("globalDescriptor"), flags=(CEZF,) + br label("globalDescriptor"), flags=(CEZF,) ld t3, tsl, [1, t0, t3], dataSize=8 - bri t0, label("processDescriptor") + br label("processDescriptor") globalDescriptor: ld t3, tsg, [1, t0, t3], dataSize=8 processDescriptor: @@ -112,7 +112,7 @@ processDescriptor: wrdl cs, t3, t2 wrsel cs, t2 wrip t0, t1 - bri t0, label("end") + br label("end") # Do other stuff if they're not. end: diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py index d965735f5..1e2c0c42f 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py @@ -240,12 +240,12 @@ def macroop MOV_REAL_S_P { def macroop MOV_S_R { andi t0, regm, 0xFC, flags=(EZF,), dataSize=2 - bri t0, label("processDescriptor"), flags=(CEZF,) + br label("processDescriptor"), flags=(CEZF,) andi t2, regm, 0xF8, dataSize=8 andi t0, regm, 0x4, flags=(EZF,), dataSize=2 - bri t0, label("globalDescriptor"), flags=(CEZF,) + br label("globalDescriptor"), flags=(CEZF,) ld t3, tsl, [1, t0, t2], dataSize=8 - bri t0, label("processDescriptor") + br label("processDescriptor") globalDescriptor: ld t3, tsg, [1, t0, t2], dataSize=8 processDescriptor: @@ -257,12 +257,12 @@ processDescriptor: def macroop MOV_S_M { ld t1, seg, sib, disp, dataSize=2 andi t0, t1, 0xFC, flags=(EZF,), dataSize=2 - bri t0, label("processDescriptor"), flags=(CEZF,) + br label("processDescriptor"), flags=(CEZF,) andi t2, t1, 0xF8, dataSize=8 andi t0, t1, 0x4, flags=(EZF,), dataSize=2 - bri t0, label("globalDescriptor"), flags=(CEZF,) + br label("globalDescriptor"), flags=(CEZF,) ld t3, tsl, [1, t0, t2], dataSize=8 - bri t0, label("processDescriptor") + br label("processDescriptor") globalDescriptor: ld t3, tsg, [1, t0, t2], dataSize=8 processDescriptor: @@ -275,12 +275,12 @@ def macroop MOV_S_P { rdip t7 ld t1, seg, riprel, disp, dataSize=2 andi t0, t1, 0xFC, flags=(EZF,), dataSize=2 - bri t0, label("processDescriptor"), flags=(CEZF,) + br label("processDescriptor"), flags=(CEZF,) andi t2, t1, 0xF8, dataSize=8 andi t0, t1, 0x4, flags=(EZF,), dataSize=2 - bri t0, label("globalDescriptor"), flags=(CEZF,) + br label("globalDescriptor"), flags=(CEZF,) ld t3, tsl, [1, t0, t2], dataSize=8 - bri t0, label("processDescriptor") + br label("processDescriptor") globalDescriptor: ld t3, tsg, [1, t0, t2], dataSize=8 processDescriptor: @@ -291,12 +291,12 @@ processDescriptor: def macroop MOVSS_S_R { andi t0, regm, 0xFC, flags=(EZF,), dataSize=2 - bri t0, label("processDescriptor"), flags=(CEZF,) + br label("processDescriptor"), flags=(CEZF,) andi t2, regm, 0xF8, dataSize=8 andi t0, regm, 0x4, flags=(EZF,), dataSize=2 - bri t0, label("globalDescriptor"), flags=(CEZF,) + br label("globalDescriptor"), flags=(CEZF,) ld t3, tsl, [1, t0, t2], dataSize=8 - bri t0, label("processDescriptor") + br label("processDescriptor") globalDescriptor: ld t3, tsg, [1, t0, t2], dataSize=8 processDescriptor: @@ -308,12 +308,12 @@ processDescriptor: def macroop MOVSS_S_M { ld t1, seg, sib, disp, dataSize=2 andi t0, t1, 0xFC, flags=(EZF,), dataSize=2 - bri t0, label("processDescriptor"), flags=(CEZF,) + br label("processDescriptor"), flags=(CEZF,) andi t2, t1, 0xF8, dataSize=8 andi t0, t1, 0x4, flags=(EZF,), dataSize=2 - bri t0, label("globalDescriptor"), flags=(CEZF,) + br label("globalDescriptor"), flags=(CEZF,) ld t3, tsl, [1, t0, t2], dataSize=8 - bri t0, label("processDescriptor") + br label("processDescriptor") globalDescriptor: ld t3, tsg, [1, t0, t2], dataSize=8 processDescriptor: @@ -326,12 +326,12 @@ def macroop MOVSS_S_P { rdip t7 ld t1, seg, riprel, disp, dataSize=2 andi t0, t1, 0xFC, flags=(EZF,), dataSize=2 - bri t0, label("processDescriptor"), flags=(CEZF,) + br label("processDescriptor"), flags=(CEZF,) andi t2, t1, 0xF8, dataSize=8 andi t0, t1, 0x4, flags=(EZF,), dataSize=2 - bri t0, label("globalDescriptor"), flags=(CEZF,) + br label("globalDescriptor"), flags=(CEZF,) ld t3, tsl, [1, t0, t2], dataSize=8 - bri t0, label("processDescriptor") + br label("processDescriptor") globalDescriptor: ld t3, tsg, [1, t0, t2], dataSize=8 processDescriptor: diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py index 64efd7dc9..8ec957d11 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py @@ -175,11 +175,11 @@ def macroop ENTER_I_I { # If the nesting level is zero, skip all this stuff. subi t0, t1, t0, flags=(EZF,), dataSize=2 - bri t0, label("skipLoop"), flags=(CEZF,) + br label("skipLoop"), flags=(CEZF,) # If the level was 1, only push the saved rbp subi t0, t1, 1, flags=(EZF,) - bri t0, label("bottomOfLoop"), flags=(CEZF,) + br label("bottomOfLoop"), flags=(CEZF,) limm t4, "ULL(-1)", dataSize=8 topOfLoop: @@ -189,7 +189,7 @@ topOfLoop: # If we're not done yet, loop subi t4, t4, 1, dataSize=8 add t0, t4, t1, flags=(EZF,) - bri t0, label("topOfLoop"), flags=(nCEZF,) + br label("topOfLoop"), flags=(nCEZF,) bottomOfLoop: # Push the old rbp onto the stack diff --git a/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py b/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py index 29b722d66..9d1d4e724 100644 --- a/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py +++ b/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py @@ -71,7 +71,7 @@ def macroop INS_M_R { def macroop INS_E_M_R { and t0, rcx, rcx, flags=(EZF,), dataSize=asz - bri t0, label("end"), flags=(CEZF,) + br label("end"), flags=(CEZF,) # Find the constant we need to either add or subtract from rdi ruflag t0, 10 movi t3, t3, dsz, flags=(CEZF,), dataSize=asz @@ -86,7 +86,7 @@ topOfLoop: subi rcx, rcx, 1, flags=(EZF,), dataSize=asz add rdi, rdi, t3, dataSize=asz - bri t0, label("topOfLoop"), flags=(nCEZF,) + br label("topOfLoop"), flags=(nCEZF,) end: fault "NoFault" }; @@ -108,7 +108,7 @@ def macroop OUTS_R_M { def macroop OUTS_E_R_M { and t0, rcx, rcx, flags=(EZF,), dataSize=asz - bri t0, label("end"), flags=(CEZF,) + br label("end"), flags=(CEZF,) # Find the constant we need to either add or subtract from rdi ruflag t0, 10 movi t3, t3, dsz, flags=(CEZF,), dataSize=asz @@ -123,7 +123,7 @@ topOfLoop: subi rcx, rcx, 1, flags=(EZF,), dataSize=asz add rsi, rsi, t3, dataSize=asz - bri t0, label("topOfLoop"), flags=(nCEZF,) + br label("topOfLoop"), flags=(nCEZF,) end: fault "NoFault" }; diff --git a/src/arch/x86/isa/insts/general_purpose/string/compare_strings.py b/src/arch/x86/isa/insts/general_purpose/string/compare_strings.py index 9810fe3c2..561b8a415 100644 --- a/src/arch/x86/isa/insts/general_purpose/string/compare_strings.py +++ b/src/arch/x86/isa/insts/general_purpose/string/compare_strings.py @@ -76,7 +76,7 @@ def macroop CMPS_M_M { def macroop CMPS_E_M_M { and t0, rcx, rcx, flags=(EZF,), dataSize=asz - bri t0, label("end"), flags=(CEZF,) + br label("end"), flags=(CEZF,) # Find the constant we need to either add or subtract from rdi ruflag t0, 10 @@ -92,14 +92,14 @@ topOfLoop: subi rcx, rcx, 1, flags=(EZF,), dataSize=asz add rdi, rdi, t3, dataSize=asz add rsi, rsi, t3, dataSize=asz - bri t0, label("topOfLoop"), flags=(CSTRZnEZF,) + br label("topOfLoop"), flags=(CSTRZnEZF,) end: fault "NoFault" }; def macroop CMPS_N_M_M { and t0, rcx, rcx, flags=(EZF,), dataSize=asz - bri t0, label("end"), flags=(CEZF,) + br label("end"), flags=(CEZF,) # Find the constant we need to either add or subtract from rdi ruflag t0, 10 @@ -115,7 +115,7 @@ topOfLoop: subi rcx, rcx, 1, flags=(EZF,), dataSize=asz add rdi, rdi, t3, dataSize=asz add rsi, rsi, t3, dataSize=asz - bri t0, label("topOfLoop"), flags=(CSTRnZnEZF,) + br label("topOfLoop"), flags=(CSTRnZnEZF,) end: fault "NoFault" }; diff --git a/src/arch/x86/isa/insts/general_purpose/string/load_string.py b/src/arch/x86/isa/insts/general_purpose/string/load_string.py index 8cf07fea6..8d144dc4d 100644 --- a/src/arch/x86/isa/insts/general_purpose/string/load_string.py +++ b/src/arch/x86/isa/insts/general_purpose/string/load_string.py @@ -68,7 +68,7 @@ def macroop LODS_M { def macroop LODS_E_M { and t0, rcx, rcx, flags=(EZF,), dataSize=asz - bri t0, label("end"), flags=(CEZF,) + br label("end"), flags=(CEZF,) # Find the constant we need to either add or subtract from rdi ruflag t0, 10 movi t3, t3, dsz, flags=(CEZF,), dataSize=asz @@ -80,7 +80,7 @@ topOfLoop: subi rcx, rcx, 1, flags=(EZF,), dataSize=asz add rdi, rdi, t3, dataSize=asz - bri t0, label("topOfLoop"), flags=(nCEZF,) + br label("topOfLoop"), flags=(nCEZF,) end: fault "NoFault" }; diff --git a/src/arch/x86/isa/insts/general_purpose/string/move_string.py b/src/arch/x86/isa/insts/general_purpose/string/move_string.py index 1d7dd75ad..18faa38e2 100644 --- a/src/arch/x86/isa/insts/general_purpose/string/move_string.py +++ b/src/arch/x86/isa/insts/general_purpose/string/move_string.py @@ -70,7 +70,7 @@ def macroop MOVS_M_M { def macroop MOVS_E_M_M { and t0, rcx, rcx, flags=(EZF,), dataSize=asz - bri t0, label("end"), flags=(CEZF,) + br label("end"), flags=(CEZF,) # Find the constant we need to either add or subtract from rdi ruflag t0, 10 movi t3, t3, dsz, flags=(CEZF,), dataSize=asz @@ -84,7 +84,7 @@ topOfLoop: subi rcx, rcx, 1, flags=(EZF,), dataSize=asz add rdi, rdi, t3, dataSize=asz add rsi, rsi, t3, dataSize=asz - bri t0, label("topOfLoop"), flags=(nCEZF,) + br label("topOfLoop"), flags=(nCEZF,) end: fault "NoFault" }; diff --git a/src/arch/x86/isa/insts/general_purpose/string/scan_string.py b/src/arch/x86/isa/insts/general_purpose/string/scan_string.py index b37e367be..5b0e74aad 100644 --- a/src/arch/x86/isa/insts/general_purpose/string/scan_string.py +++ b/src/arch/x86/isa/insts/general_purpose/string/scan_string.py @@ -74,7 +74,7 @@ def macroop SCAS_M { def macroop SCAS_E_M { and t0, rcx, rcx, flags=(EZF,), dataSize=asz - bri t0, label("end"), flags=(CEZF,) + br label("end"), flags=(CEZF,) # Find the constant we need to either add or subtract from rdi ruflag t0, 10 @@ -88,14 +88,14 @@ topOfLoop: subi rcx, rcx, 1, flags=(EZF,), dataSize=asz add rdi, rdi, t2, dataSize=asz - bri t0, label("topOfLoop"), flags=(CSTRZnEZF,) + br label("topOfLoop"), flags=(CSTRZnEZF,) end: fault "NoFault" }; def macroop SCAS_N_M { and t0, rcx, rcx, flags=(EZF,), dataSize=asz - bri t0, label("end"), flags=(CEZF,) + br label("end"), flags=(CEZF,) # Find the constant we need to either add or subtract from rdi ruflag t0, 10 @@ -109,7 +109,7 @@ topOfLoop: subi rcx, rcx, 1, flags=(EZF,), dataSize=asz add rdi, rdi, t2, dataSize=asz - bri t0, label("topOfLoop"), flags=(CSTRnZnEZF,) + br label("topOfLoop"), flags=(CSTRnZnEZF,) end: fault "NoFault" }; diff --git a/src/arch/x86/isa/insts/general_purpose/string/store_string.py b/src/arch/x86/isa/insts/general_purpose/string/store_string.py index b52b1f1fb..fe9917ce6 100644 --- a/src/arch/x86/isa/insts/general_purpose/string/store_string.py +++ b/src/arch/x86/isa/insts/general_purpose/string/store_string.py @@ -68,7 +68,7 @@ def macroop STOS_M { def macroop STOS_E_M { and t0, rcx, rcx, flags=(EZF,), dataSize=asz - bri t0, label("end"), flags=(CEZF,) + br label("end"), flags=(CEZF,) # Find the constant we need to either add or subtract from rdi ruflag t0, 10 movi t3, t3, dsz, flags=(CEZF,), dataSize=asz @@ -80,7 +80,7 @@ topOfLoop: subi rcx, rcx, 1, flags=(EZF,), dataSize=asz add rdi, rdi, t3, dataSize=asz - bri t0, label("topOfLoop"), flags=(nCEZF,) + br label("topOfLoop"), flags=(nCEZF,) end: fault "NoFault" }; diff --git a/src/arch/x86/isa/microops/microops.isa b/src/arch/x86/isa/microops/microops.isa index 1c9e8358a..19266f6d6 100644 --- a/src/arch/x86/isa/microops/microops.isa +++ b/src/arch/x86/isa/microops/microops.isa @@ -68,6 +68,9 @@ //Load/store microop definitions ##include "ldstop.isa" +//Control flow microop definitions +##include "seqop.isa" + //Miscellaneous microop definitions ##include "specop.isa" diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index b751b9b4f..d0d7062ff 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -843,10 +843,6 @@ let {{ code = 'RIP = psrc1 + sop2 + CSBase' else_code="RIP = RIP;" - class Br(WrRegOp, CondRegOp): - code = 'nuIP = psrc1 + op2;' - else_code='nuIP = nuIP;' - class Wruflags(WrRegOp): code = 'ccFlagBits = psrc1 ^ op2' diff --git a/src/arch/x86/isa/microops/seqop.isa b/src/arch/x86/isa/microops/seqop.isa new file mode 100644 index 000000000..821afbe83 --- /dev/null +++ b/src/arch/x86/isa/microops/seqop.isa @@ -0,0 +1,208 @@ +// Copyright (c) 2008 The Hewlett-Packard Development Company +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the +// following conditions are met: +// +// The software must be used only for Non-Commercial Use which means any +// use which is NOT directed to receiving any direct monetary +// compensation for, or commercial advantage from such use. Illustrative +// examples of non-commercial use are academic research, personal study, +// teaching, education and corporate research & development. +// Illustrative examples of commercial use are distributing products for +// commercial advantage and providing services using the software for +// commercial advantage. +// +// If you wish to use this software or functionality therein that may be +// covered by patents for commercial use, please contact: +// Director of Intellectual Property Licensing +// Office of Strategy and Technology +// Hewlett-Packard Company +// 1501 Page Mill Road +// Palo Alto, California 94304 +// +// Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. Redistributions +// in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or +// other materials provided with the distribution. Neither the name of +// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. No right of +// sublicense is granted herewith. Derivatives of the software and +// output created using the software may be prepared, but only for +// Non-Commercial Uses. Derivatives of the software may be shared with +// others provided: (i) the others agree to abide by the list of +// conditions herein which includes the Non-Commercial Use restrictions; +// and (ii) such Derivatives of the software include the above copyright +// notice to acknowledge the contribution from this software where +// applicable, this list of conditions and the disclaimer below. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Gabe Black + +output header {{ + class SeqOpBase : public X86ISA::X86MicroopBase + { + protected: + uint16_t target; + uint8_t cc; + + public: + SeqOpBase(ExtMachInst _machInst, const char * instMnem, + const char * mnemonic, + bool isMicro, bool isDelayed, bool isFirst, bool isLast, + uint16_t _target, uint8_t _cc); + + SeqOpBase(ExtMachInst _machInst, const char * instMnem, + const char * mnemonic, + uint16_t _target, uint8_t _cc); + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + }; +}}; + +def template SeqOpDeclare {{ + class %(class_name)s : public %(base_class)s + { + private: + void buildMe(); + public: + %(class_name)s(ExtMachInst _machInst, const char * instMnem, + bool isMicro, bool isDelayed, bool isFirst, bool isLast, + uint16_t _target, uint8_t _cc); + + %(class_name)s(ExtMachInst _machInst, const char * instMnem, + uint16_t _target, uint8_t _cc); + + %(BasicExecDeclare)s + }; +}}; + +def template SeqOpExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + %(op_decl)s; + %(op_rd)s; + if (%(cond_test)s) { + %(code)s; + } else { + %(else_code)s; + } + %(op_wb)s; + return NoFault; + } +}}; + +output decoder {{ + inline SeqOpBase::SeqOpBase( + ExtMachInst machInst, const char * mnemonic, const char * instMnem, + uint16_t _target, uint8_t _cc) : + X86MicroopBase(machInst, mnemonic, instMnem, + false, false, false, false, No_OpClass), + target(_target), cc(_cc) + { + } + + inline SeqOpBase::SeqOpBase( + ExtMachInst machInst, const char * mnemonic, const char * instMnem, + bool isMicro, bool isDelayed, bool isFirst, bool isLast, + uint16_t _target, uint8_t _cc) : + X86MicroopBase(machInst, mnemonic, instMnem, + isMicro, isDelayed, isFirst, isLast, No_OpClass), + target(_target), cc(_cc) + { + } +}}; + +def template SeqOpConstructor {{ + + inline void %(class_name)s::buildMe() + { + %(constructor)s; + } + + inline %(class_name)s::%(class_name)s( + ExtMachInst machInst, const char * instMnem, + uint16_t _target, uint8_t _cc) : + %(base_class)s(machInst, "%(mnemonic)s", instMnem, _target, _cc) + { + buildMe(); + } + + inline %(class_name)s::%(class_name)s( + ExtMachInst machInst, const char * instMnem, + bool isMicro, bool isDelayed, bool isFirst, bool isLast, + uint16_t _target, uint8_t _cc) : + %(base_class)s(machInst, "%(mnemonic)s", instMnem, + isMicro, isDelayed, isFirst, isLast, _target, _cc) + { + buildMe(); + } +}}; + +output decoder {{ + std::string SeqOpBase::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream response; + + printMnemonic(response, instMnem, mnemonic); + ccprintf(response, "%#x", target); + + return response.str(); + } +}}; + +let {{ + class Br(X86Microop): + className = "MicroBranch" + def __init__(self, target, flags=None): + self.target = target + if flags: + if not isinstance(flags, (list, tuple)): + raise Exception, "flags must be a list or tuple of flags" + self.cond = " | ".join(flags) + self.className += "Flags" + else: + self.cond = "0" + + def getAllocator(self, *microFlags): + allocator = '''new %(class_name)s(machInst, mnemonic + %(flags)s, %(target)s, %(cc)s)''' % { + "class_name" : self.className, + "flags" : self.microFlagsText(microFlags), + "target" : self.target, + "cc" : self.cond} + return allocator + + iop = InstObjParams("br", "MicroBranchFlags", "SeqOpBase", + {"code": "nuIP = target", + "else_code": "nuIP = nuIP", + "cond_test": "checkCondition(ccFlagBits, cc)"}) + exec_output += SeqOpExecute.subst(iop) + header_output += SeqOpDeclare.subst(iop) + decoder_output += SeqOpConstructor.subst(iop) + iop = InstObjParams("br", "MicroBranch", "SeqOpBase", + {"code": "nuIP = target", + "else_code": "nuIP = nuIP", + "cond_test": "true"}) + exec_output += SeqOpExecute.subst(iop) + header_output += SeqOpDeclare.subst(iop) + decoder_output += SeqOpConstructor.subst(iop) + microopClasses["br"] = Br +}}; -- cgit v1.2.3 From 4aa18aa80022d9e4125faab8ff1f5123e159137d Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 15:43:35 -0700 Subject: X86: Make Br never report itself as the last microop. --- src/arch/x86/isa/microops/seqop.isa | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/seqop.isa b/src/arch/x86/isa/microops/seqop.isa index 821afbe83..603f4458b 100644 --- a/src/arch/x86/isa/microops/seqop.isa +++ b/src/arch/x86/isa/microops/seqop.isa @@ -169,8 +169,7 @@ output decoder {{ }}; let {{ - class Br(X86Microop): - className = "MicroBranch" + class SeqOp(X86Microop): def __init__(self, target, flags=None): self.target = target if flags: @@ -190,6 +189,15 @@ let {{ "cc" : self.cond} return allocator + class Br(SeqOp): + className = "MicroBranch" + + def getAllocator(self, *microFlags): + (is_micro, is_delayed, is_first, is_last) = microFlags + is_last = False + microFlags = (is_micro, is_delayed, is_first, is_last) + return super(Br, self).getAllocator(*microFlags) + iop = InstObjParams("br", "MicroBranchFlags", "SeqOpBase", {"code": "nuIP = target", "else_code": "nuIP = nuIP", -- cgit v1.2.3 From 6fd4eff68f53ec1cd9194581bfa223bfbaa2d83d Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 15:53:04 -0700 Subject: X86: Create an eret microop which returns from ROM to combinational decoding. --- src/arch/x86/isa/microops/seqop.isa | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/seqop.isa b/src/arch/x86/isa/microops/seqop.isa index 603f4458b..d3c7bf096 100644 --- a/src/arch/x86/isa/microops/seqop.isa +++ b/src/arch/x86/isa/microops/seqop.isa @@ -198,6 +198,25 @@ let {{ microFlags = (is_micro, is_delayed, is_first, is_last) return super(Br, self).getAllocator(*microFlags) + class Eret(SeqOp): + target = "normalMicroPC(0)" + className = "Eret" + + def __init__(self, flags=None): + if flags: + if not isinstance(flags, (list, tuple)): + raise Exception, "flags must be a list or tuple of flags" + self.cond = " | ".join(flags) + self.className += "Flags" + else: + self.cond = "0" + + def getAllocator(self, *microFlags): + (is_micro, is_delayed, is_first, is_last) = microFlags + is_last = True + microFlags = (is_micro, is_delayed, is_first, is_last) + return super(Eret, self).getAllocator(*microFlags) + iop = InstObjParams("br", "MicroBranchFlags", "SeqOpBase", {"code": "nuIP = target", "else_code": "nuIP = nuIP", @@ -213,4 +232,18 @@ let {{ header_output += SeqOpDeclare.subst(iop) decoder_output += SeqOpConstructor.subst(iop) microopClasses["br"] = Br + + iop = InstObjParams("eret", "EretFlags", "SeqOpBase", + {"code": "", "else_code": "", + "cond_test": "checkCondition(ccFlagBits, cc)"}) + exec_output += SeqOpExecute.subst(iop) + header_output += SeqOpDeclare.subst(iop) + decoder_output += SeqOpConstructor.subst(iop) + iop = InstObjParams("eret", "Eret", "SeqOpBase", + {"code": "", "else_code": "", + "cond_test": "true"}) + exec_output += SeqOpExecute.subst(iop) + header_output += SeqOpDeclare.subst(iop) + decoder_output += SeqOpConstructor.subst(iop) + microopClasses["eret"] = Eret }}; -- cgit v1.2.3 From 2736086d7c67a24d9eb87827a22a2b352e342ba2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 15:59:21 -0700 Subject: CPU: Create a microcode ROM object in the CPU which is defined by the ISA. --- src/arch/SConscript | 1 + src/arch/alpha/microcode_rom.hh | 41 +++++++++++++++++++++++++++++++++++++++++ src/arch/mips/microcode_rom.hh | 41 +++++++++++++++++++++++++++++++++++++++++ src/arch/sparc/microcode_rom.hh | 41 +++++++++++++++++++++++++++++++++++++++++ src/arch/x86/microcode_rom.hh | 41 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 165 insertions(+) create mode 100644 src/arch/alpha/microcode_rom.hh create mode 100644 src/arch/mips/microcode_rom.hh create mode 100644 src/arch/sparc/microcode_rom.hh create mode 100644 src/arch/x86/microcode_rom.hh (limited to 'src/arch') diff --git a/src/arch/SConscript b/src/arch/SConscript index 66f93870e..932cf7509 100644 --- a/src/arch/SConscript +++ b/src/arch/SConscript @@ -49,6 +49,7 @@ isa_switch_hdrs = Split(''' isa_traits.hh kernel_stats.hh locked_mem.hh + microcode_rom.hh mmaped_ipr.hh process.hh predecoder.hh diff --git a/src/arch/alpha/microcode_rom.hh b/src/arch/alpha/microcode_rom.hh new file mode 100644 index 000000000..ef0602580 --- /dev/null +++ b/src/arch/alpha/microcode_rom.hh @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2008 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef __ARCH_ALPHA_MICROCODE_ROM_HH__ +#define __ARCH_ALPHA_MICROCODE_ROM_HH__ + +#include "sim/microcode_rom.hh" + +namespace AlphaISA +{ + using ::MicrocodeRom; +} + +#endif // __ARCH_ALPHA_MICROCODE_ROM_HH__ diff --git a/src/arch/mips/microcode_rom.hh b/src/arch/mips/microcode_rom.hh new file mode 100644 index 000000000..a5be81e2a --- /dev/null +++ b/src/arch/mips/microcode_rom.hh @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2008 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef __ARCH_MIPS_MICROCODE_ROM_HH__ +#define __ARCH_MIPS_MICROCODE_ROM_HH__ + +#include "sim/microcode_rom.hh" + +namespace MipsISA +{ + using ::MicrocodeRom; +} + +#endif // __ARCH_MIPS_MICROCODE_ROM_HH__ diff --git a/src/arch/sparc/microcode_rom.hh b/src/arch/sparc/microcode_rom.hh new file mode 100644 index 000000000..e46000dcc --- /dev/null +++ b/src/arch/sparc/microcode_rom.hh @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2008 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef __ARCH_SPARC_MICROCODE_ROM_HH__ +#define __ARCH_SPARC_MICROCODE_ROM_HH__ + +#include "sim/microcode_rom.hh" + +namespace SparcISA +{ + using ::MicrocodeRom; +} + +#endif // __ARCH_SPARC_MICROCODE_ROM_HH__ diff --git a/src/arch/x86/microcode_rom.hh b/src/arch/x86/microcode_rom.hh new file mode 100644 index 000000000..1495ff699 --- /dev/null +++ b/src/arch/x86/microcode_rom.hh @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2008 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef __ARCH_X86_MICROCODE_ROM_HH__ +#define __ARCH_X86_MICROCODE_ROM_HH__ + +#include "sim/microcode_rom.hh" + +namespace X86ISA +{ + using ::MicrocodeRom; +} + +#endif // __ARCH_X86_MICROCODE_ROM_HH__ -- cgit v1.2.3 From e5f80924671bf0cfaf02c51f4b98d529631733f1 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 17:48:44 -0700 Subject: X86: Make X86's microcode ROM actually do something. --- src/arch/x86/isa/includes.isa | 1 + src/arch/x86/isa/macroop.isa | 20 +++++++-- src/arch/x86/isa/microasm.isa | 10 ++++- src/arch/x86/isa/microops/base.isa | 30 +++++++++++++ src/arch/x86/isa/rom.isa | 90 ++++++++++++++++++++++++++++++++++++++ src/arch/x86/microcode_rom.hh | 37 +++++++++++++++- 6 files changed, 181 insertions(+), 7 deletions(-) create mode 100644 src/arch/x86/isa/rom.isa (limited to 'src/arch') diff --git a/src/arch/x86/isa/includes.isa b/src/arch/x86/isa/includes.isa index 926e9185a..e523b7e32 100644 --- a/src/arch/x86/isa/includes.isa +++ b/src/arch/x86/isa/includes.isa @@ -113,6 +113,7 @@ output header {{ output decoder {{ #include "arch/x86/faults.hh" #include "arch/x86/floatregs.hh" +#include "arch/x86/microcode_rom.hh" #include "arch/x86/miscregs.hh" #include "arch/x86/segmentregs.hh" #include "base/cprintf.hh" diff --git a/src/arch/x86/isa/macroop.isa b/src/arch/x86/isa/macroop.isa index 4818b926c..b851a92c7 100644 --- a/src/arch/x86/isa/macroop.isa +++ b/src/arch/x86/isa/macroop.isa @@ -76,12 +76,13 @@ output header {{ { protected: const uint32_t numMicroops; + X86ISA::EmulEnv emulEnv; //Constructor. Macroop(const char *mnem, ExtMachInst _machInst, - uint32_t _numMicroops) + uint32_t _numMicroops, X86ISA::EmulEnv _emulEnv) : StaticInst(mnem, _machInst, No_OpClass), - numMicroops(_numMicroops) + numMicroops(_numMicroops), emulEnv(_emulEnv) { assert(numMicroops); microops = new StaticInstPtr[numMicroops]; @@ -107,7 +108,20 @@ output header {{ return mnemonic; } + public: %(MacroExecPanic)s + + ExtMachInst + getExtMachInst() + { + return machInst; + } + + X86ISA::EmulEnv + getEmulEnv() + { + return emulEnv; + } }; }}; @@ -139,7 +153,7 @@ def template MacroDeclare {{ def template MacroConstructor {{ inline X86Macroop::%(class_name)s::%(class_name)s( ExtMachInst machInst, EmulEnv env) - : %(base_class)s("%(mnemonic)s", machInst, %(num_microops)s) + : %(base_class)s("%(mnemonic)s", machInst, %(num_microops)s, env) { %(adjust_env)s; %(adjust_imm)s; diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index 735a7722c..9a5019f10 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -64,13 +64,16 @@ //Include code to build macroops in both C++ and python. ##include "macroop.isa" +//Include code to fill out the microcode ROM in both C++ and python. +##include "rom.isa" + let {{ import sys sys.path[0:0] = ["src/arch/x86/isa/"] from insts import microcode # print microcode - from micro_asm import MicroAssembler, Rom_Macroop, Rom - mainRom = Rom('main ROM') + from micro_asm import MicroAssembler, Rom_Macroop + mainRom = X86MicrocodeRom('main ROM') assembler = MicroAssembler(X86Macroop, microopClasses, mainRom, Rom_Macroop) # Add in symbols for the microcode registers for num in range(15): @@ -186,4 +189,7 @@ let {{ assembler.symbols["st"] = stack_index macroopDict = assembler.assemble(microcode) + + decoder_output += mainRom.getDefinition() + header_output += mainRom.getDeclaration() }}; diff --git a/src/arch/x86/isa/microops/base.isa b/src/arch/x86/isa/microops/base.isa index 75658a26c..994e997d8 100644 --- a/src/arch/x86/isa/microops/base.isa +++ b/src/arch/x86/isa/microops/base.isa @@ -69,6 +69,28 @@ let {{ let {{ class X86Microop(object): + + generatorNameTemplate = "generate_%s_%d" + + generatorTemplate = ''' + StaticInstPtr + ''' + generatorNameTemplate + '''(StaticInstPtr curMacroop) + { + static const char * mnemonic = romMnemonic; + static const ExtMachInst dummyExtMachInst; + static const EmulEnv dummyEmulEnv(0, 0, 1, 1, 1); + + Macroop * macroop = dynamic_cast(curMacroop.get()); + const ExtMachInst &machInst = + macroop ? macroop->getExtMachInst() : dummyExtMachInst; + const EmulEnv &env = + macroop ? macroop->getEmulEnv() : dummyEmulEnv; + // env may not be used in the microop's constructor. + RegIndex reg = env.reg; + reg = reg; + return %s; + } + ''' def __init__(self, name): self.name = name @@ -91,4 +113,12 @@ let {{ def getAllocator(self, mnemonic, *microFlags): return 'new %s(machInst, %s)' % \ (self.className, mnemonic, self.microFlagsText(microFlags)) + + def getGeneratorDef(self, micropc): + return self.generatorTemplate % \ + (self.className, micropc, \ + self.getAllocator(True, False, False, False)) + + def getGenerator(self, micropc): + return self.generatorNameTemplate % (self.className, micropc) }}; diff --git a/src/arch/x86/isa/rom.isa b/src/arch/x86/isa/rom.isa new file mode 100644 index 000000000..7d3eb8670 --- /dev/null +++ b/src/arch/x86/isa/rom.isa @@ -0,0 +1,90 @@ +// Copyright (c) 2008 The Regents of The University of Michigan +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Gabe Black + +def template MicroRomConstructor {{ + + %(define_generators)s + const MicroPC X86ISA::MicrocodeRom::numMicroops = %(num_microops)s; + + X86ISA::MicrocodeRom::MicrocodeRom() + { + using namespace RomLabels; + genFuncs = new GenFunc[numMicroops]; + %(alloc_generators)s; + } +}}; + +let {{ + from micro_asm import Rom + + class X86MicrocodeRom(Rom): + def __init__(self, name): + super(X86MicrocodeRom, self).__init__(name) + self.directives = {} + + def add_microop(self, mnemonic, microop): + microop.mnemonic = mnemonic + microop.micropc = len(self.microops) + self.microops.append(microop) + + + def getDeclaration(self): + declareLabels = "namespace RomLabels {\n" + for (label, microop) in self.labels.items(): + declareLabels += "const static uint64_t label_%s = %d;\n" \ + % (label, microop.micropc) + for (label, microop) in self.externs.items(): + declareLabels += \ + "const static MicroPC extern_label_%s = %d;\n" \ + % (label, microop.micropc) + declareLabels += "}\n" + return declareLabels; + + def getDefinition(self): + numMicroops = len(self.microops) + allocGenerators = '' + micropc = 0 + define_generators = ''' + namespace + { + static const char romMnemonic[] = "Microcode_ROM"; + ''' + for op in self.microops: + define_generators += op.getGeneratorDef(micropc) + allocGenerators += "genFuncs[%d] = %s;\n" % \ + (micropc, op.getGenerator(micropc)) + micropc += 1 + define_generators += "}\n" + iop = InstObjParams(self.name, self.name, "MicrocodeRom", + {"code" : "", + "define_generators" : define_generators, + "num_microops" : numMicroops, + "alloc_generators" : allocGenerators + }) + return MicroRomConstructor.subst(iop); +}}; diff --git a/src/arch/x86/microcode_rom.hh b/src/arch/x86/microcode_rom.hh index 1495ff699..f8ad410ce 100644 --- a/src/arch/x86/microcode_rom.hh +++ b/src/arch/x86/microcode_rom.hh @@ -31,11 +31,44 @@ #ifndef __ARCH_X86_MICROCODE_ROM_HH__ #define __ARCH_X86_MICROCODE_ROM_HH__ -#include "sim/microcode_rom.hh" +#include "arch/x86/emulenv.hh" +#include "cpu/static_inst.hh" + +namespace X86ISAInst +{ + class MicrocodeRom + { + protected: + + typedef StaticInstPtr (*GenFunc)(StaticInstPtr); + + static const MicroPC numMicroops; + + GenFunc * genFuncs; + + public: + //Constructor. + MicrocodeRom(); + + //Destructor. + ~MicrocodeRom() + { + delete [] genFuncs; + } + + StaticInstPtr + fetchMicroop(MicroPC microPC, StaticInstPtr curMacroop) + { + microPC = normalMicroPC(microPC); + assert(microPC < numMicroops); + return genFuncs[microPC](curMacroop); + } + }; +} namespace X86ISA { - using ::MicrocodeRom; + using X86ISAInst::MicrocodeRom; } #endif // __ARCH_X86_MICROCODE_ROM_HH__ -- cgit v1.2.3 From cefb768131b1d0582c5cbe83feaa97060dfe15af Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 17:52:51 -0700 Subject: X86: Create a handy way to access labels from the ROM in microcode. --- src/arch/x86/isa/microasm.isa | 5 +++++ src/arch/x86/isa/microops/base.isa | 1 + src/arch/x86/isa/rom.isa | 3 --- 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index 9a5019f10..d7b008145 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -183,6 +183,11 @@ let {{ assembler.symbols["label"] = labeler + def rom_labeler(labelStr): + return "romMicroPC(RomLabels::extern_label_%s)" % labelStr + + assembler.symbols["rom_label"] = rom_labeler + def stack_index(index): return "(NUM_FLOATREGS + (((%s) + 8) %% 8))" % index diff --git a/src/arch/x86/isa/microops/base.isa b/src/arch/x86/isa/microops/base.isa index 994e997d8..057d237ad 100644 --- a/src/arch/x86/isa/microops/base.isa +++ b/src/arch/x86/isa/microops/base.isa @@ -88,6 +88,7 @@ let {{ // env may not be used in the microop's constructor. RegIndex reg = env.reg; reg = reg; + using namespace RomLabels; return %s; } ''' diff --git a/src/arch/x86/isa/rom.isa b/src/arch/x86/isa/rom.isa index 7d3eb8670..59b280056 100644 --- a/src/arch/x86/isa/rom.isa +++ b/src/arch/x86/isa/rom.isa @@ -55,9 +55,6 @@ let {{ def getDeclaration(self): declareLabels = "namespace RomLabels {\n" - for (label, microop) in self.labels.items(): - declareLabels += "const static uint64_t label_%s = %d;\n" \ - % (label, microop.micropc) for (label, microop) in self.externs.items(): declareLabels += \ "const static MicroPC extern_label_%s = %d;\n" \ -- cgit v1.2.3 From f245358343fb26ac976d15b8f2a023caa0f9ba0d Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 17:57:46 -0700 Subject: Get rid of old RegContext code. --- src/arch/alpha/regfile.hh | 7 ------- src/arch/alpha/types.hh | 7 ------- src/arch/mips/regfile.cc | 6 ------ src/arch/mips/regfile/regfile.hh | 4 ---- src/arch/mips/types.hh | 3 --- src/arch/sparc/miscregfile.cc | 3 --- src/arch/sparc/regfile.cc | 15 --------------- src/arch/sparc/regfile.hh | 2 -- src/arch/sparc/types.hh | 8 -------- src/arch/x86/regfile.cc | 5 ----- src/arch/x86/regfile.hh | 2 -- src/arch/x86/types.hh | 11 ----------- 12 files changed, 73 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh index d6d2f587e..e431e7570 100644 --- a/src/arch/alpha/regfile.hh +++ b/src/arch/alpha/regfile.hh @@ -206,13 +206,6 @@ class RegFile { void serialize(EventManager *em, std::ostream &os); void unserialize(EventManager *em, Checkpoint *cp, const std::string §ion); - - void - changeContext(RegContextParam param, RegContextVal val) - { - //This would be an alternative place to call/implement - //the swapPALShadow function - } }; static inline int diff --git a/src/arch/alpha/types.hh b/src/arch/alpha/types.hh index 94a4cb0e9..7905114b8 100644 --- a/src/arch/alpha/types.hh +++ b/src/arch/alpha/types.hh @@ -57,13 +57,6 @@ union AnyReg MiscReg ctrlreg; }; -enum RegContextParam -{ - CONTEXT_PALMODE -}; - -typedef bool RegContextVal; - enum annotes { ANNOTE_NONE = 0, diff --git a/src/arch/mips/regfile.cc b/src/arch/mips/regfile.cc index 0c670af6d..e05bfe2df 100644 --- a/src/arch/mips/regfile.cc +++ b/src/arch/mips/regfile.cc @@ -188,12 +188,6 @@ RegFile::unserialize(Checkpoint *cp, const std::string §ion) } - -void RegFile::changeContext(RegContextParam param, RegContextVal val) -{ - panic("Change Context Not Implemented for MipsISA"); -} - static inline int flattenIntIndex(ThreadContext * tc, int reg) { return reg; diff --git a/src/arch/mips/regfile/regfile.hh b/src/arch/mips/regfile/regfile.hh index 076cf45f5..ebf793396 100644 --- a/src/arch/mips/regfile/regfile.hh +++ b/src/arch/mips/regfile/regfile.hh @@ -104,10 +104,6 @@ namespace MipsISA void unserialize(EventManager *em, Checkpoint *cp, const std::string §ion); - void changeContext(RegContextParam param, RegContextVal val) - { - } - }; } // namespace MipsISA diff --git a/src/arch/mips/types.hh b/src/arch/mips/types.hh index 4208cb2d8..b459d9e14 100644 --- a/src/arch/mips/types.hh +++ b/src/arch/mips/types.hh @@ -60,9 +60,6 @@ namespace MipsISA MiscReg ctrlreg; } AnyReg; - typedef int RegContextParam; - typedef int RegContextVal; - //used in FP convert & round function enum ConvertType{ SINGLE_TO_DOUBLE, diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index d66cefa7a..b0c5dbda9 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -551,11 +551,8 @@ void MiscRegFile::setReg(int miscReg, new_val = val >= NWindows ? NWindows - 1 : val; if (val >= NWindows) new_val = NWindows - 1; - - tc->changeRegFileContext(CONTEXT_CWP, new_val); break; case MISCREG_GL: - tc->changeRegFileContext(CONTEXT_GLOBALS, val); break; case MISCREG_PIL: case MISCREG_SOFTINT: diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc index 8815b094c..f390be508 100644 --- a/src/arch/sparc/regfile.cc +++ b/src/arch/sparc/regfile.cc @@ -241,21 +241,6 @@ RegFile::unserialize(EventManager *em, Checkpoint *cp, const string §ion) UNSERIALIZE_SCALAR(nnpc); } -void RegFile::changeContext(RegContextParam param, RegContextVal val) -{ - switch(param) - { - case CONTEXT_CWP: - intRegFile.setCWP(val); - break; - case CONTEXT_GLOBALS: - intRegFile.setGlobals(val); - break; - default: - panic("Tried to set illegal context parameter in the SPARC regfile.\n"); - } -} - void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest) { diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh index da7e022e9..dd4e1f684 100644 --- a/src/arch/sparc/regfile.hh +++ b/src/arch/sparc/regfile.hh @@ -117,8 +117,6 @@ namespace SparcISA const std::string §ion); public: - - void changeContext(RegContextParam param, RegContextVal val); }; int flattenIntIndex(ThreadContext * tc, int reg); diff --git a/src/arch/sparc/types.hh b/src/arch/sparc/types.hh index d19e2a99f..dd369cc26 100644 --- a/src/arch/sparc/types.hh +++ b/src/arch/sparc/types.hh @@ -51,14 +51,6 @@ namespace SparcISA MiscReg ctrlreg; } AnyReg; - enum RegContextParam - { - CONTEXT_CWP, - CONTEXT_GLOBALS - }; - - typedef int RegContextVal; - typedef uint16_t RegIndex; struct CoreSpecific { diff --git a/src/arch/x86/regfile.cc b/src/arch/x86/regfile.cc index 78fde7474..7d01c4bb4 100644 --- a/src/arch/x86/regfile.cc +++ b/src/arch/x86/regfile.cc @@ -248,11 +248,6 @@ RegFile::unserialize(EventManager *em, Checkpoint *cp, const string §ion) UNSERIALIZE_SCALAR(nextRip); } -void RegFile::changeContext(RegContextParam param, RegContextVal val) -{ - panic("changeContext not implemented for x86!\n"); -} - void X86ISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest) { panic("copyMiscRegs not implemented for x86!\n"); diff --git a/src/arch/x86/regfile.hh b/src/arch/x86/regfile.hh index 3c2387346..75c0290d3 100644 --- a/src/arch/x86/regfile.hh +++ b/src/arch/x86/regfile.hh @@ -145,8 +145,6 @@ namespace X86ISA const std::string §ion); public: - - void changeContext(RegContextParam param, RegContextVal val); }; int flattenIntIndex(ThreadContext * tc, int reg); diff --git a/src/arch/x86/types.hh b/src/arch/x86/types.hh index 90df38d13..29420352b 100644 --- a/src/arch/x86/types.hh +++ b/src/arch/x86/types.hh @@ -246,17 +246,6 @@ namespace X86ISA MiscReg ctrlReg; } AnyReg; - //XXX This is very hypothetical. X87 instructions would need to - //change their "context" constantly. It's also not clear how - //this would be handled as far as out of order execution. - //Maybe x87 instructions are in order? - enum RegContextParam - { - CONTEXT_X87_TOP - }; - - typedef int RegContextVal; - typedef uint16_t RegIndex; struct CoreSpecific { -- cgit v1.2.3 From 223fc41c076fe53d21bc3e8b951baff7e01468fa Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 20:07:46 -0700 Subject: X86: Fix the rdbase microop --- src/arch/x86/isa/microops/regop.isa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index d0d7062ff..dfb0abeae 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -1001,7 +1001,7 @@ let {{ class Rdbase(SegOp): code = ''' - DestReg = SegBaseDest; + DestReg = SegBaseSrc1; ''' class Rdlimit(SegOp): -- cgit v1.2.3 From e9158d763a34d96147d62d08f6ccc4e8ba3308e5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 20:17:38 -0700 Subject: X86: Let the microassembler know about the microcode only H segment. --- src/arch/x86/isa/microasm.isa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index d7b008145..75e1dc524 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -81,7 +81,7 @@ let {{ for num in range(7): assembler.symbols["ufp%d" % num] = "FLOATREG_MICROFP(%d)" % num # Add in symbols for the segment descriptor registers - for letter in ("C", "D", "E", "F", "G", "S"): + for letter in ("C", "D", "E", "F", "G", "H", "S"): assembler.symbols["%ss" % letter.lower()] = "SEGMENT_REG_%sS" % letter # Add in symbols for the various checks of segment selectors. -- cgit v1.2.3 From 9e1fe2050ac55c28b6601770014193321a4013d0 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 20:25:06 -0700 Subject: X86: Let segment manipulation microops be conditional. --- src/arch/x86/isa/microops/regop.isa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index dfb0abeae..4f93fad80 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -978,7 +978,7 @@ let {{ ''' # Microops for manipulating segmentation registers - class SegOp(RegOp): + class SegOp(CondRegOp): abstract = True def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): super(SegOp, self).__init__(dest, \ -- cgit v1.2.3 From 15f5bb3055b70a43ba8b504b1453f51b2a6e1ee3 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 20:29:52 -0700 Subject: X86: Fix chks checking the submode for stack segments. --- src/arch/x86/isa/microops/regop.isa | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 4f93fad80..b7883b2e2 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -1048,7 +1048,8 @@ let {{ return new StackFault; } } else { - if ((m5reg.mode != SixtyFourBitMode || m5reg.cpl == 3) || + if ((m5reg.submode != SixtyFourBitMode || + m5reg.cpl == 3) || !(desc.s == 1 && desc.type.codeOrData == 0 && desc.type.w) || (desc.dpl != m5reg.cpl) || -- cgit v1.2.3 From 30feb90c1cba922a7dac38204900e29b4788b935 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 20:33:37 -0700 Subject: X86: Add a check type for interrupt gates. --- src/arch/x86/isa/microasm.isa | 2 +- src/arch/x86/isa/microops/regop.isa | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index 75e1dc524..29ec6dc94 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -85,7 +85,7 @@ let {{ assembler.symbols["%ss" % letter.lower()] = "SEGMENT_REG_%sS" % letter # Add in symbols for the various checks of segment selectors. - for check in ("NoCheck", "CSCheck", "CallGateCheck", + for check in ("NoCheck", "CSCheck", "CallGateCheck", "IntGateCheck", "SSCheck", "IretCheck", "IntCSCheck"): assembler.symbols[check] = "Seg%s" % check diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index b7883b2e2..0d019729f 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -233,7 +233,7 @@ output header {{ uint64_t "ient, uint64_t &remainder); enum SegmentSelectorCheck { - SegNoCheck, SegCSCheck, SegCallGateCheck, + SegNoCheck, SegCSCheck, SegCallGateCheck, SegIntGateCheck, SegSSCheck, SegIretCheck, SegIntCSCheck }; }}; @@ -1041,6 +1041,11 @@ let {{ panic("CS checks for far calls/jumps through call gates" "not implemented.\\n"); break; + case SegIntGateCheck: + if (desc.dpl < m5reg.cpl) { + return new GeneralProtection((uint16_t)selector); + } + break; case SegSSCheck: if (selector.si || selector.ti) { if (!desc.p) { -- cgit v1.2.3 From 6b46e5204d52c8e46b48541d5112f7e9a1cadc43 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 20:38:22 -0700 Subject: X86: Implement the chks check of interrupt gate target code segments. --- src/arch/x86/isa/microops/regop.isa | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 0d019729f..ba996060c 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -1076,8 +1076,14 @@ let {{ break; } case SegIntCSCheck: - panic("CS selector checks for interrupts and exceptions" - "not implemented.\\n"); + if (m5reg.mode == LongMode) { + if (desc.l != 1 || desc.d != 0) { + return new GeneralProtection(selector); + } + } else { + panic("Interrupt CS checks not implemented " + "in legacy mode.\\n"); + } break; default: panic("Undefined segment check type.\\n"); -- cgit v1.2.3 From 6074b1abf2e235f9a5d3ad78879a805ca335dc0e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 20:44:11 -0700 Subject: X86: Implement local labels for the ROM that actually refer into the ROM. --- src/arch/x86/isa/microasm.isa | 5 +++++ src/arch/x86/isa/rom.isa | 3 +++ 2 files changed, 8 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index 29ec6dc94..81aa1dafe 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -188,6 +188,11 @@ let {{ assembler.symbols["rom_label"] = rom_labeler + def rom_local_labeler(labelStr): + return "romMicroPC(RomLabels::label_%s)" % labelStr + + assembler.symbols["rom_local_label"] = rom_local_labeler + def stack_index(index): return "(NUM_FLOATREGS + (((%s) + 8) %% 8))" % index diff --git a/src/arch/x86/isa/rom.isa b/src/arch/x86/isa/rom.isa index 59b280056..7d3eb8670 100644 --- a/src/arch/x86/isa/rom.isa +++ b/src/arch/x86/isa/rom.isa @@ -55,6 +55,9 @@ let {{ def getDeclaration(self): declareLabels = "namespace RomLabels {\n" + for (label, microop) in self.labels.items(): + declareLabels += "const static uint64_t label_%s = %d;\n" \ + % (label, microop.micropc) for (label, microop) in self.externs.items(): declareLabels += \ "const static MicroPC extern_label_%s = %d;\n" \ -- cgit v1.2.3 From 961b40cdb537382f6463479e3707e7d04a223f38 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 22:16:53 -0700 Subject: X86: Implement an wrdh microop which loads bases/offsets from 16 byte descriptors. --- src/arch/x86/isa/microops/regop.isa | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index ba996060c..d7d1e3063 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -236,6 +236,15 @@ output header {{ SegNoCheck, SegCSCheck, SegCallGateCheck, SegIntGateCheck, SegSSCheck, SegIretCheck, SegIntCSCheck }; + + enum LongModeDescriptorType { + LDT64 = 2, + AvailableTSS64 = 9, + BusyTSS64 = 0xb, + CallGate64 = 0xc, + IntGate64 = 0xe, + TrapGate64 = 0xf + }; }}; output decoder {{ @@ -1098,7 +1107,26 @@ let {{ class Wrdh(RegOp): code = ''' + SegDescriptor desc = SrcReg1; + uint64_t target = bits(SrcReg2, 31, 0) << 32; + switch(desc.type) { + case LDT64: + case AvailableTSS64: + case BusyTSS64: + replaceBits(target, 23, 0, desc.baseLow); + replaceBits(target, 31, 24, desc.baseHigh); + break; + case CallGate64: + case IntGate64: + case TrapGate64: + replaceBits(target, 15, 0, bits(desc, 15, 0)); + replaceBits(target, 31, 16, bits(desc, 63, 48)); + break; + default: + panic("Wrdh used with wrong descriptor type!\\n"); + } + DestReg = target; ''' class Wrtsc(WrRegOp): -- cgit v1.2.3 From f813a4be4954bfedb95747b4635b38b1a13ee8a6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 22:24:06 -0700 Subject: X86: Make sure register microops set fault rather than returning one. --- src/arch/x86/isa/microops/regop.isa | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index d7d1e3063..439116145 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -1052,14 +1052,14 @@ let {{ break; case SegIntGateCheck: if (desc.dpl < m5reg.cpl) { - return new GeneralProtection((uint16_t)selector); + fault = new GeneralProtection((uint16_t)selector); } break; case SegSSCheck: if (selector.si || selector.ti) { if (!desc.p) { //FIXME This needs to also push the selector. - return new StackFault; + fault = new StackFault; } } else { if ((m5reg.submode != SixtyFourBitMode || @@ -1068,7 +1068,7 @@ let {{ desc.type.codeOrData == 0 && desc.type.w) || (desc.dpl != m5reg.cpl) || (selector.rpl != m5reg.cpl)) { - return new GeneralProtection(psrc1 & 0xFFFF); + fault = new GeneralProtection(psrc1 & 0xFFFF); } } break; @@ -1078,16 +1078,17 @@ let {{ (selector.rpl < m5reg.cpl) || !(desc.s == 1 && desc.type.codeOrData == 1) || (!desc.type.c && desc.dpl != selector.rpl) || - (desc.type.c && desc.dpl > selector.rpl)) - return new GeneralProtection(psrc1 & 0xFFFF); - if (!desc.p) - return new SegmentNotPresent; + (desc.type.c && desc.dpl > selector.rpl)) { + fault = new GeneralProtection(psrc1 & 0xFFFF); + } else if (!desc.p) { + fault = new SegmentNotPresent; + } break; } case SegIntCSCheck: if (m5reg.mode == LongMode) { if (desc.l != 1 || desc.d != 0) { - return new GeneralProtection(selector); + fault = new GeneralProtection(selector); } } else { panic("Interrupt CS checks not implemented " -- cgit v1.2.3 From 4c19c56a7706c7382f46c4f8c7dd10c2b2c8746a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 22:42:03 -0700 Subject: X86: Implement entering an interrupt in microcode. --- src/arch/x86/SConscript | 1 + src/arch/x86/isa/insts/__init__.py | 3 +- src/arch/x86/isa/insts/romutil.py | 201 +++++++++++++++++++++++++++++++++++++ 3 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 src/arch/x86/isa/insts/romutil.py (limited to 'src/arch') diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript index cd2445c7e..c2081156d 100644 --- a/src/arch/x86/SConscript +++ b/src/arch/x86/SConscript @@ -185,6 +185,7 @@ if env['TARGET_ISA'] == 'x86': 'general_purpose/string/scan_string.py', 'general_purpose/string/store_string.py', 'general_purpose/system_calls.py', + 'romutil.py', 'system/__init__.py', 'system/halt.py', 'system/invlpg.py', diff --git a/src/arch/x86/isa/insts/__init__.py b/src/arch/x86/isa/insts/__init__.py index 0ef617a87..d7a8bde19 100644 --- a/src/arch/x86/isa/insts/__init__.py +++ b/src/arch/x86/isa/insts/__init__.py @@ -53,7 +53,8 @@ # # Authors: Gabe Black -categories = ["general_purpose", +categories = ["romutil", + "general_purpose", "simd128", "simd64", "system", diff --git a/src/arch/x86/isa/insts/romutil.py b/src/arch/x86/isa/insts/romutil.py new file mode 100644 index 000000000..9645ee85d --- /dev/null +++ b/src/arch/x86/isa/insts/romutil.py @@ -0,0 +1,201 @@ +# Copyright (c) 2008 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Gabe Black + +microcode = ''' +def rom +{ + # This vectors the CPU into an interrupt handler in long mode. + # On entry, t1 is set to the vector of the interrupt and t7 is the current + # ip. We need that because rdip returns the next ip. + extern longModeInterrupt: + + # + # Get the 64 bit interrupt or trap gate descriptor from the IDT + # + + # Load the gate descriptor from the IDT + slli t4, t1, 4, dataSize=8 + ld t2, idtr, [1, t0, t4], 8, dataSize=8, addressSize=8 + ld t4, idtr, [1, t0, t4], dataSize=8, addressSize=8 + + # Check permissions + chks t1, t4, IntGateCheck + + mov t1, t1, t4, dataSize=8 + + # Check that it's the right type + srli t4, t1, 40, dataSize=8 + andi t4, t4, 0xe, dataSize=8 + xori t4, t4, 0xe, flags=(EZF,), dataSize=8 + fault "new GeneralProtection(0)", flags=(nCEZF,) + + + # + # Get the target CS descriptor using the selector in the gate + # descriptor. + # + srli t4, t1, 16, dataSize=8 + andi t5, t4, 0xF8, dataSize=8 + andi t0, t4, 0x4, flags=(EZF,), dataSize=2 + br rom_local_label("globalDescriptor"), flags=(CEZF,) + ld t3, tsl, [1, t0, t5], dataSize=8, addressSize=8 + br rom_local_label("processDescriptor") +globalDescriptor: + ld t3, tsg, [1, t0, t5], dataSize=8, addressSize=8 +processDescriptor: + chks t4, t3, IntCSCheck, dataSize=8 + wrdl hs, t3, t4, dataSize=8 + + # Check that the target offset is in canonical form + wrdh t4, t1, t2, dataSize=8 + srli t4, t4, 47, dataSize=8 + addi t4, t4, 1, dataSize=8 + srli t4, t4, 1, dataSize=8 + or t4, t4, t4, flags=(EZF,), dataSize=2 + fault "new GeneralProtection(0)", flags=(nCEZF,) + + + # + # Figure out where the stack should be + # + + # Record what we might set the stack selector to. + rdsel t6, ss + wrsel hs, t6 + + # Check if we're changing privelege level. At this point we can assume + # we're going to a DPL that's less than or equal to the CPL. + rdattr t4, hs, dataSize=8 + srli t4, t4, 3, dataSize=8 + andi t4, t4, 3, dataSize=8 + rdattr t5, cs, dataSize=8 + srli t5, t5, 3, dataSize=8 + sub t5, t5, t4, dataSize=8 + andi t0, t5, 0x3, flags=(EZF,), dataSize=8 + # We're going to change priviledge, so zero out the stack selector. We + # need to let the IST have priority so we don't branch yet. + limm t4, 0 + wrsel hs, t4, flags=(nCEZF,) + + # Check the IST field of the gate descriptor + srli t4, t1, 32, dataSize=8 + andi t4, t4, 0x7, dataSize=8 + subi t0, t4, 1, flags=(ECF,), dataSize=8 + br rom_local_label("istStackSwitch"), flags=(nCECF,) + br rom_local_label("cplStackSwitch"), flags=(nCEZF,) + + # If we're here, it's because the stack isn't being switched. + # Set t6 to the new rsp. + subi t6, rsp, 40, dataSize=8 + + # Align the stack + andi t6, t6, 0xF0, dataSize=1 + + # Check that we can access everything we need to on the stack + ldst t0, hs, [1, t0, t6], dataSize=8, addressSize=8 + ldst t0, hs, [1, t0, t6], 32, dataSize=8, addressSize=8 + br rom_local_label("stackSwitched") + +istStackSwitch: + panic "IST based stack switching isn't implemented" + br rom_local_label("stackSwitched") + +cplStackSwitch: + panic "CPL change initiated stack switching isn't implemented" + +stackSwitched: + + + ## + ## Point of no return. + ## We're now going to irrevocably modify visible state. + ## Anything bad that's going to happen should have happened by now. + ## + + + # + # Build up the interrupt stack frame + # + + # Write out the contents of memory + st t7, hs, [1, t0, t6], dataSize=8 + limm t5, 0, dataSize=8 + rdsel t5, cs, dataSize=2 + st t5, hs, [1, t0, t6], 8, dataSize=8 + rflags t4, dataSize=8 + st t4, hs, [1, t0, t6], 16, dataSize=8 + st rsp, hs, [1, t0, t6], 24, dataSize=8 + rdsel t5, ss, dataSize=2 + st t5, hs, [1, t0, t6], 32, dataSize=8 + + # Set the stack segment + mov rsp, rsp, t6, dataSize=8 + rdsel t7, hs, dataSize=2 + wrsel ss, t7, dataSize=2 + + # + # Set up the target code segment + # + srli t5, t1, 16, dataSize=8 + andi t5, t5, 0xFF, dataSize=8 + wrdl cs, t3, t5, dataSize=8 + wrsel cs, t5, dataSize=2 + wrdh t7, t1, t2, dataSize=8 + wrip t0, t7, dataSize=8 + + # + # Adjust rflags which is still in t4 from above + # + + # Set IF to the lowest bit of the original gate type. + # The type field of the original gate starts at bit 40. + + # Set the TF, NT, and RF bits. We'll flip them at the end. + limm t6, (1 << 8) | (1 << 14) | (1 << 16) + or t4, t4, t6 + srli t5, t1, 40, dataSize=8 + srli t7, t4, 9, dataSize=8 + xor t5, t7, t5, dataSize=8 + andi t5, t5, 1, dataSize=8 + slli t5, t5, 9, dataSize=8 + or t6, t5, t6, dataSize=8 + + # Put the results into rflags + wrflags t6, t4 + + eret +}; + +def rom +{ + # This vectors the CPU into an interrupt handler in legacy mode. + extern legacyModeInterrupt: + panic "Legacy mode interrupts not implemented (in microcode)" + eret +}; +''' -- cgit v1.2.3 From 9e8e2f9ec6ae4ea3be8f5280a1ca4cb734e3e068 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 22:42:10 -0700 Subject: X86: Make the x86 interrupt fault kick off the interrupt microcode. --- src/arch/x86/faults.cc | 14 +++++++++++++- src/arch/x86/faults.hh | 19 +++++++++---------- 2 files changed, 22 insertions(+), 11 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/faults.cc b/src/arch/x86/faults.cc index 1c94a1251..18680899e 100644 --- a/src/arch/x86/faults.cc +++ b/src/arch/x86/faults.cc @@ -85,6 +85,7 @@ * Authors: Gabe Black */ +#include "arch/x86/decoder.hh" #include "arch/x86/faults.hh" #include "base/trace.hh" #include "config/full_system.hh" @@ -112,7 +113,18 @@ namespace X86ISA void X86Interrupt::invoke(ThreadContext * tc) { - panic("X86 faults are not implemented!"); + using namespace X86ISAInst::RomLabels; + HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG); + MicroPC entry; + if (m5reg.mode == LongMode) { + entry = extern_label_longModeInterrupt; + } else { + entry = extern_label_legacyModeInterrupt; + } + tc->setIntReg(INTREG_MICRO(1), vector); + tc->setIntReg(INTREG_MICRO(7), tc->readPC()); + tc->setMicroPC(romMicroPC(entry)); + tc->setNextMicroPC(romMicroPC(entry) + 1); } void FakeITLBFault::invoke(ThreadContext * tc) diff --git a/src/arch/x86/faults.hh b/src/arch/x86/faults.hh index b15ad15d1..b7948a638 100644 --- a/src/arch/x86/faults.hh +++ b/src/arch/x86/faults.hh @@ -137,9 +137,10 @@ namespace X86ISA class X86Interrupt : public X86FaultBase { protected: - X86Interrupt(const char * name, const char * mnem, + uint8_t vector; + X86Interrupt(const char * name, const char * mnem, uint8_t _vector, uint64_t _errorCode = 0) : - X86FaultBase(name, mnem, _errorCode) + X86FaultBase(name, mnem, _errorCode), vector(_vector) {} #if FULL_SYSTEM @@ -215,10 +216,9 @@ namespace X86ISA class NonMaskableInterrupt : public X86Interrupt { - uint8_t vector; public: NonMaskableInterrupt(uint8_t _vector) : - X86Interrupt("Non Maskable Interrupt", "#NMI"), vector(_vector) + X86Interrupt("Non Maskable Interrupt", "#NMI", _vector) {} }; @@ -352,10 +352,9 @@ namespace X86ISA class ExternalInterrupt : public X86Interrupt { - uint8_t vector; public: ExternalInterrupt(uint8_t _vector) : - X86Interrupt("External Interrupt", "#INTR"), vector(_vector) + X86Interrupt("External Interrupt", "#INTR", _vector) {} }; @@ -363,7 +362,7 @@ namespace X86ISA { public: SystemManagementInterrupt() : - X86Interrupt("System Management Interrupt", "#SMI") + X86Interrupt("System Management Interrupt", "#SMI", 0) {} }; @@ -372,15 +371,15 @@ namespace X86ISA uint8_t vector; public: InitInterrupt(uint8_t _vector) : - X86Interrupt("INIT Interrupt", "#INIT"), vector(_vector) + X86Interrupt("INIT Interrupt", "#INIT", _vector) {} }; class SoftwareInterrupt : public X86Interrupt { public: - SoftwareInterrupt() : - X86Interrupt("Software Interrupt", "INTn") + SoftwareInterrupt(uint8_t _vector) : + X86Interrupt("Software Interrupt", "INTn", _vector) {} }; -- cgit v1.2.3 From a2e0d539d89643ce5243be9b8a0be4c3bcee7520 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 22:55:55 -0700 Subject: X86: Add wrval/rdval microops for reading significant miscregs. --- src/arch/x86/isa/microasm.isa | 5 +++++ src/arch/x86/isa/microops/regop.isa | 16 ++++++++++++++++ src/arch/x86/isa/operands.isa | 6 ++++-- 3 files changed, 25 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index 81aa1dafe..f9e0a2fa8 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -159,6 +159,11 @@ let {{ assembler.symbols["CTrue"] = "ConditionTests::True" assembler.symbols["CFalse"] = "ConditionTests::False" + for reg in ('sysenter_cs', 'sysenter_esp', 'sysenter_eip', + 'star', 'lstar', 'cstar', 'sf_mask', + 'kernel_gs_base'): + assembler.symbols[reg] = "MISCREG_%s" % reg.upper() + # Code literal which forces a default 64 bit operand size in 64 bit mode. assembler.symbols["oszIn64Override"] = ''' if (machInst.mode.submode == SixtyFourBitMode && diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 439116145..944d5e9ec 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -1028,6 +1028,22 @@ let {{ DestReg = SegSelSrc1; ''' + class Rdval(RegOp): + def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): + super(Rdval, self).__init__(dest, \ + src1, "NUM_INTREGS", flags, dataSize) + code = ''' + DestReg = MiscRegSrc1; + ''' + + class Wrval(RegOp): + def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): + super(Wrval, self).__init__(dest, \ + src1, "NUM_INTREGS", flags, dataSize) + code = ''' + MiscRegDest = SrcReg1; + ''' + class Chks(RegOp): def __init__(self, dest, src1, src2=0, flags=None, dataSize="env.dataSize"): diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index 8bb7c5bb1..343b37d41 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -153,7 +153,9 @@ def operands {{ 'GDTRLimit': ('ControlReg', 'uqw', 'MISCREG_TSG_LIMIT', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 206), 'CSBase': ('ControlReg', 'udw', 'MISCREG_CS_EFF_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 207), 'CSAttr': ('ControlReg', 'udw', 'MISCREG_CS_ATTR', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 208), - 'TscOp': ('ControlReg', 'udw', 'MISCREG_TSC', (None, None, ['IsSerializeAfter', 'IsSerializing', 'IsNonSpeculative']), 209), - 'M5Reg': ('ControlReg', 'udw', 'MISCREG_M5_REG', (None, None, None), 210), + 'MiscRegDest': ('ControlReg', 'uqw', 'dest', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 209), + 'MiscRegSrc1': ('ControlReg', 'uqw', 'src1', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 210), + 'TscOp': ('ControlReg', 'udw', 'MISCREG_TSC', (None, None, ['IsSerializeAfter', 'IsSerializing', 'IsNonSpeculative']), 211), + 'M5Reg': ('ControlReg', 'udw', 'MISCREG_M5_REG', (None, None, None), 212), 'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 300) }}; -- cgit v1.2.3 From 564eda827bc9ebe3bacfb9a44838e4abc1deb61b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 23:00:07 -0700 Subject: X86: Implement the swapgs instruction. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 2 +- src/arch/x86/isa/insts/system/segmentation.py | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index bceb0595e..b8013165e 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -128,7 +128,7 @@ 0x4: smsw_Rv(); 0x6: lmsw_Rv(); 0x7: decode MODRM_RM { - 0x0: swapgs(); + 0x0: Inst::SWAPGS(); 0x1: rdtscp(); default: Inst::UD2(); } diff --git a/src/arch/x86/isa/insts/system/segmentation.py b/src/arch/x86/isa/insts/system/segmentation.py index 97846f79c..49d8eb110 100644 --- a/src/arch/x86/isa/insts/system/segmentation.py +++ b/src/arch/x86/isa/insts/system/segmentation.py @@ -167,4 +167,12 @@ def macroop LIDT_16_P wrbase idtr, t2 wrlimit idtr, t1 }; + +def macroop SWAPGS +{ + rdval t1, kernel_gs_base, dataSize=8 + rdbase t2, gs, dataSize=8 + wrbase gs, t1, dataSize=8 + wrval kernel_gs_base, t2, dataSize=8 +}; ''' -- cgit v1.2.3 From 349a155b6e38c128f155b1c83d9f11e73f6e8673 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 23:00:28 -0700 Subject: X86: Panic when an unimplemented fault is invoked, rather than spinning forever --- src/arch/x86/faults.hh | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/faults.hh b/src/arch/x86/faults.hh index b7948a638..3bcacffe2 100644 --- a/src/arch/x86/faults.hh +++ b/src/arch/x86/faults.hh @@ -91,6 +91,12 @@ namespace X86ISA { return mnem; } + + void + invoke(ThreadContext * tc) + { + panic("Unimplemented fault %s.\n", name()); + } }; // Base class for x86 faults which behave as if the underlying instruction -- cgit v1.2.3 From e3004c579fcd7c3f34dfcbd90169c5aa9218a65b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 23:05:22 -0700 Subject: X86: Fix the segment setting code in IRET, and make it restore the flags. --- .../general_purpose/control_transfer/interrupts_and_exceptions.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py index 125866ce5..57bc13698 100644 --- a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py +++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py @@ -190,8 +190,8 @@ processSSDescriptor: # This actually updates state which is wrong. It should wait until we know # we're not going to fault. Unfortunately, that's hard to do. - wrdl cs, t7, t2 - wrsel cs, t2 + wrdl ss, t7, t2 + wrsel ss, t2 ### ### From this point downwards, we can't fault. We can update user visible state. @@ -224,6 +224,7 @@ skipSegmentSquashing: # Ignore this for now. #RFLAGS.v = temp_RFLAGS + wrflags t0, t3 # VIF,VIP,IOPL only changed if (old_CPL = 0) # IF only changed if (old_CPL <= old_RFLAGS.IOPL) # VM unchanged -- cgit v1.2.3 From fd376882940db45bdf7abf2fff8758b162828b83 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 23:27:45 -0700 Subject: X86: Add some DPRINTFs to the local APIC. --- src/arch/x86/interrupts.cc | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index 280fa5dd1..148b26157 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -474,14 +474,20 @@ bool X86ISA::Interrupts::check_interrupts(ThreadContext * tc) const { RFLAGS rflags = tc->readMiscRegNoEffect(MISCREG_RFLAGS); - if (pendingUnmaskableInt) + if (pendingUnmaskableInt) { + DPRINTF(LocalApic, "Reported pending unmaskable interrupt.\n"); return true; + } if (rflags.intf) { - if (pendingExtInt) + if (pendingExtInt) { + DPRINTF(LocalApic, "Reported pending external interrupt.\n"); return true; + } if (IRRV > ISRV && bits(IRRV, 7, 4) > - bits(regs[APIC_TASK_PRIORITY], 7, 4)) + bits(regs[APIC_TASK_PRIORITY], 7, 4)) { + DPRINTF(LocalApic, "Reported pending regular interrupt.\n"); return true; + } } return false; } @@ -494,10 +500,13 @@ X86ISA::Interrupts::getInterrupt(ThreadContext * tc) // check for. if (pendingUnmaskableInt) { if (pendingSmi) { + DPRINTF(LocalApic, "Generated SMI fault object.\n"); return new SystemManagementInterrupt(); } else if (pendingNmi) { + DPRINTF(LocalApic, "Generated NMI fault object.\n"); return new NonMaskableInterrupt(nmiMessage.vector); } else if (pendingInit) { + DPRINTF(LocalApic, "Generated INIT fault object.\n"); return new InitInterrupt(initMessage.vector); } else { panic("pendingUnmaskableInt set, but no unmaskable " @@ -505,8 +514,10 @@ X86ISA::Interrupts::getInterrupt(ThreadContext * tc) return NoFault; } } else if (pendingExtInt) { + DPRINTF(LocalApic, "Generated external interrupt fault object.\n"); return new ExternalInterrupt(extIntMessage.vector); } else { + DPRINTF(LocalApic, "Generated regular interrupt fault object.\n"); // The only thing left are fixed and lowest priority interrupts. return new ExternalInterrupt(IRRV); } @@ -518,10 +529,13 @@ X86ISA::Interrupts::updateIntrInfo(ThreadContext * tc) assert(check_interrupts(tc)); if (pendingUnmaskableInt) { if (pendingSmi) { + DPRINTF(LocalApic, "SMI sent to core.\n"); pendingSmi = false; } else if (pendingNmi) { + DPRINTF(LocalApic, "NMI sent to core.\n"); pendingNmi = false; } else if (pendingInit) { + DPRINTF(LocalApic, "Init sent to core.\n"); pendingInit = false; } if (!(pendingSmi || pendingNmi || pendingInit)) @@ -529,6 +543,7 @@ X86ISA::Interrupts::updateIntrInfo(ThreadContext * tc) } else if (pendingExtInt) { pendingExtInt = false; } else { + DPRINTF(LocalApic, "Interrupt %d sent to core.\n", IRRV); // Mark the interrupt as "in service". ISRV = IRRV; setRegArrayBit(APIC_IN_SERVICE_BASE, ISRV); -- cgit v1.2.3 From bdc28d793dd9b3407c513fba5c24917aa423f7ca Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 23:28:11 -0700 Subject: X86: Implement the EOI register in the local APIC. --- src/arch/x86/interrupts.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index 148b26157..df1b40e5b 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -330,9 +330,6 @@ X86ISA::Interrupts::readReg(ApicRegIndex reg) case APIC_PROCESSOR_PRIORITY: panic("Local APIC Processor Priority register unimplemented.\n"); break; - case APIC_EOI: - panic("Local APIC EOI register unimplemented.\n"); - break; case APIC_ERROR_STATUS: regs[APIC_INTERNAL_STATE] &= ~ULL(0x1); break; @@ -391,8 +388,10 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val) panic("Local APIC Processor Priority register unimplemented.\n"); break; case APIC_EOI: - panic("Local APIC EOI register unimplemented.\n"); - break; + // Remove the interrupt that just completed from the local apic state. + clearRegArrayBit(APIC_IN_SERVICE_BASE, ISRV); + updateISRV(); + return; case APIC_LOGICAL_DESTINATION: newVal = val & 0xFF000000; break; -- cgit v1.2.3 From 33ebd04474a1042e5cce585802481b6e95a4e92e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 23:28:49 -0700 Subject: X86: Make the local APIC timer event generate an interrupt. --- src/arch/x86/interrupts.cc | 93 +++++++++++++++++++++++----------------------- src/arch/x86/interrupts.hh | 50 ++++++++++++++++++++----- 2 files changed, 87 insertions(+), 56 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index df1b40e5b..bbc651378 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -240,6 +240,48 @@ X86ISA::Interrupts::write(PacketPtr pkt) setReg(reg, gtoh(val)); return latency; } +void +X86ISA::Interrupts::requestInterrupt(uint8_t vector, + uint8_t deliveryMode, bool level) +{ + /* + * Fixed and lowest-priority delivery mode interrupts are handled + * using the IRR/ISR registers, checking against the TPR, etc. + * The SMI, NMI, ExtInt, INIT, etc interrupts go straight through. + */ + if (deliveryMode == DeliveryMode::Fixed || + deliveryMode == DeliveryMode::LowestPriority) { + DPRINTF(LocalApic, "Interrupt is an %s.\n", + DeliveryMode::names[deliveryMode]); + // Queue up the interrupt in the IRR. + if (vector > IRRV) + IRRV = vector; + if (!getRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, vector)) { + setRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, vector); + if (level) { + setRegArrayBit(APIC_TRIGGER_MODE_BASE, vector); + } else { + clearRegArrayBit(APIC_TRIGGER_MODE_BASE, vector); + } + } + } else if (!DeliveryMode::isReserved(deliveryMode)) { + DPRINTF(LocalApic, "Interrupt is an %s.\n", + DeliveryMode::names[deliveryMode]); + if (deliveryMode == DeliveryMode::SMI && !pendingSmi) { + pendingUnmaskableInt = pendingSmi = true; + smiVector = vector; + } else if (deliveryMode == DeliveryMode::NMI && !pendingNmi) { + pendingUnmaskableInt = pendingNmi = true; + nmiVector = vector; + } else if (deliveryMode == DeliveryMode::ExtInt && !pendingExtInt) { + pendingExtInt = true; + extIntVector = vector; + } else if (deliveryMode == DeliveryMode::INIT && !pendingInit) { + pendingUnmaskableInt = pendingInit = true; + initVector = vector; + } + } +} Tick X86ISA::Interrupts::recvMessage(PacketPtr pkt) @@ -260,49 +302,8 @@ X86ISA::Interrupts::recvMessage(PacketPtr pkt) assert((message.destMode == 0 && message.destination == id) || (bits((int)message.destination, id))); - /* - * Fixed and lowest-priority delivery mode interrupts are handled - * using the IRR/ISR registers, checking against the TPR, etc. - * The SMI, NMI, ExtInt, INIT, etc interrupts go straight through. - */ - if (message.deliveryMode == DeliveryMode::Fixed || - message.deliveryMode == DeliveryMode::LowestPriority) { - DPRINTF(LocalApic, "Interrupt is an %s.\n", - DeliveryMode::names[message.deliveryMode]); - // Queue up the interrupt in the IRR. - if (vector > IRRV) - IRRV = vector; - if (!getRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, vector)) { - setRegArrayBit(APIC_INTERRUPT_REQUEST_BASE, vector); - if (message.trigger) { - // Level triggered. - setRegArrayBit(APIC_TRIGGER_MODE_BASE, vector); - } else { - // Edge triggered. - clearRegArrayBit(APIC_TRIGGER_MODE_BASE, vector); - } - } - } else if (!DeliveryMode::isReserved(message.deliveryMode)) { - DPRINTF(LocalApic, "Interrupt is an %s.\n", - DeliveryMode::names[message.deliveryMode]); - if (message.deliveryMode == DeliveryMode::SMI && - !pendingSmi) { - pendingUnmaskableInt = pendingSmi = true; - smiMessage = message; - } else if (message.deliveryMode == DeliveryMode::NMI && - !pendingNmi) { - pendingUnmaskableInt = pendingNmi = true; - nmiMessage = message; - } else if (message.deliveryMode == DeliveryMode::ExtInt && - !pendingExtInt) { - pendingExtInt = true; - extIntMessage = message; - } else if (message.deliveryMode == DeliveryMode::INIT && - !pendingInit) { - pendingUnmaskableInt = pendingInit = true; - initMessage = message; - } - } + requestInterrupt(message.vector, + message.deliveryMode, message.trigger); } break; default: @@ -503,10 +504,10 @@ X86ISA::Interrupts::getInterrupt(ThreadContext * tc) return new SystemManagementInterrupt(); } else if (pendingNmi) { DPRINTF(LocalApic, "Generated NMI fault object.\n"); - return new NonMaskableInterrupt(nmiMessage.vector); + return new NonMaskableInterrupt(nmiVector); } else if (pendingInit) { DPRINTF(LocalApic, "Generated INIT fault object.\n"); - return new InitInterrupt(initMessage.vector); + return new InitInterrupt(initVector); } else { panic("pendingUnmaskableInt set, but no unmaskable " "ints were pending.\n"); @@ -514,7 +515,7 @@ X86ISA::Interrupts::getInterrupt(ThreadContext * tc) } } else if (pendingExtInt) { DPRINTF(LocalApic, "Generated external interrupt fault object.\n"); - return new ExternalInterrupt(extIntMessage.vector); + return new ExternalInterrupt(extIntVector); } else { DPRINTF(LocalApic, "Generated regular interrupt fault object.\n"); // The only thing left are fixed and lowest priority interrupts. diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh index 85a0f6478..a998e2b12 100644 --- a/src/arch/x86/interrupts.hh +++ b/src/arch/x86/interrupts.hh @@ -79,6 +79,17 @@ class Interrupts : public BasicPioDevice, IntDev // Storage for the APIC registers uint32_t regs[NUM_APIC_REGS]; + BitUnion32(LVTEntry) + Bitfield<7, 0> vector; + Bitfield<10, 8> deliveryMode; + Bitfield<12> status; + Bitfield<13> polarity; + Bitfield<14> remoteIRR; + Bitfield<15> trigger; + Bitfield<16> masked; + Bitfield<17> periodic; + EndBitUnion(LVTEntry) + /* * Timing related stuff. */ @@ -87,13 +98,20 @@ class Interrupts : public BasicPioDevice, IntDev class ApicTimerEvent : public Event { + private: + Interrupts *localApic; public: - ApicTimerEvent() : Event() + ApicTimerEvent(Interrupts *_localApic) : + Event(), localApic(_localApic) {} void process() { - warn("Local APIC timer event doesn't do anything!\n"); + assert(localApic); + if (localApic->triggerTimerInterrupt()) { + localApic->setReg(APIC_INITIAL_COUNT, + localApic->readReg(APIC_INITIAL_COUNT)); + } } }; @@ -104,13 +122,13 @@ class Interrupts : public BasicPioDevice, IntDev * the IRR. */ bool pendingSmi; - TriggerIntMessage smiMessage; + uint8_t smiVector; bool pendingNmi; - TriggerIntMessage nmiMessage; + uint8_t nmiVector; bool pendingExtInt; - TriggerIntMessage extIntMessage; + uint8_t extIntVector; bool pendingInit; - TriggerIntMessage initMessage; + uint8_t initVector; // This is a quick check whether any of the above (except ExtInt) are set. bool pendingUnmaskableInt; @@ -163,6 +181,8 @@ class Interrupts : public BasicPioDevice, IntDev return bits(regs[base + (vector % 32)], vector >> 5); } + void requestInterrupt(uint8_t vector, uint8_t deliveryMode, bool level); + public: /* * Params stuff. @@ -187,6 +207,15 @@ class Interrupts : public BasicPioDevice, IntDev Tick write(PacketPtr pkt); Tick recvMessage(PacketPtr pkt); + bool + triggerTimerInterrupt() + { + LVTEntry entry = regs[APIC_LVT_TIMER]; + if (!entry.masked) + requestInterrupt(entry.vector, entry.deliveryMode, entry.trigger); + return entry.periodic; + } + void addressRanges(AddrRangeList &range_list) { range_list.clear(); @@ -225,10 +254,11 @@ class Interrupts : public BasicPioDevice, IntDev Interrupts(Params * p) : BasicPioDevice(p), IntDev(this), latency(p->pio_latency), clock(0), - pendingSmi(false), smiMessage(0), - pendingNmi(false), nmiMessage(0), - pendingExtInt(false), extIntMessage(0), - pendingInit(false), initMessage(0), + apicTimerEvent(this), + pendingSmi(false), smiVector(0), + pendingNmi(false), nmiVector(0), + pendingExtInt(false), extIntVector(0), + pendingInit(false), initVector(0), pendingUnmaskableInt(false) { pioSize = PageBytes; -- cgit v1.2.3 From 3c4567f2a65e0809d84d85a3fd82a294a1b0cb96 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 12 Oct 2008 23:29:10 -0700 Subject: X86: Set the delayed commit flag in x86 microops appropriately. --- src/arch/x86/isa/macroop.isa | 6 +++--- src/arch/x86/isa/microops/base.isa | 2 +- src/arch/x86/isa/microops/seqop.isa | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/macroop.isa b/src/arch/x86/isa/macroop.isa index b851a92c7..7d94dd95c 100644 --- a/src/arch/x86/isa/macroop.isa +++ b/src/arch/x86/isa/macroop.isa @@ -220,11 +220,11 @@ let {{ allocMicroops = '' micropc = 0 for op in self.microops: + isLast = (micropc == numMicroops - 1) allocMicroops += \ "microops[%d] = %s;\n" % \ - (micropc, op.getAllocator(True, False, - micropc == 0, - micropc == numMicroops - 1)) + (micropc, op.getAllocator(True, not isLast, + micropc == 0, isLast)) micropc += 1 iop = InstObjParams(self.name, self.name, "Macroop", {"code" : "", "num_microops" : numMicroops, diff --git a/src/arch/x86/isa/microops/base.isa b/src/arch/x86/isa/microops/base.isa index 057d237ad..2b73cf563 100644 --- a/src/arch/x86/isa/microops/base.isa +++ b/src/arch/x86/isa/microops/base.isa @@ -118,7 +118,7 @@ let {{ def getGeneratorDef(self, micropc): return self.generatorTemplate % \ (self.className, micropc, \ - self.getAllocator(True, False, False, False)) + self.getAllocator(True, True, False, False)) def getGenerator(self, micropc): return self.generatorNameTemplate % (self.className, micropc) diff --git a/src/arch/x86/isa/microops/seqop.isa b/src/arch/x86/isa/microops/seqop.isa index d3c7bf096..f03094f66 100644 --- a/src/arch/x86/isa/microops/seqop.isa +++ b/src/arch/x86/isa/microops/seqop.isa @@ -195,6 +195,7 @@ let {{ def getAllocator(self, *microFlags): (is_micro, is_delayed, is_first, is_last) = microFlags is_last = False + is_delayed = True microFlags = (is_micro, is_delayed, is_first, is_last) return super(Br, self).getAllocator(*microFlags) @@ -214,6 +215,7 @@ let {{ def getAllocator(self, *microFlags): (is_micro, is_delayed, is_first, is_last) = microFlags is_last = True + is_delayed = False microFlags = (is_micro, is_delayed, is_first, is_last) return super(Eret, self).getAllocator(*microFlags) -- cgit v1.2.3 From 81f5da1e89c94fb0e4e56c80cad77561163d85d8 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 16 Oct 2008 22:22:17 -0700 Subject: get rid of local variable that's only used in an assert so fast compiles --- src/arch/x86/interrupts.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index bbc651378..bfb4d5b9c 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -294,10 +294,9 @@ X86ISA::Interrupts::recvMessage(PacketPtr pkt) case 0: { TriggerIntMessage message = pkt->get(); - uint8_t vector = message.vector; DPRINTF(LocalApic, "Got Trigger Interrupt message with vector %#x.\n", - vector); + message.vector); // Make sure we're really supposed to get this. assert((message.destMode == 0 && message.destination == id) || (bits((int)message.destination, id))); -- cgit v1.2.3 From b760b99f4d9f5469d88c67ae8a06e5f9543a43e7 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Mon, 20 Oct 2008 16:22:59 -0400 Subject: O3CPU: Undo Gabe's changes to remove hwrei and simpalcheck from O3 CPU. Removing hwrei causes the instruction after the hwrei to be fetched before the ITB/DTB_CM register is updated in a call pal call sys and thus the translation fails because the user is attempting to access a super page address. Minimally, it seems as though some sort of fetch stall or refetch after a hwrei is required. I think this works currently because the hwrei uses the exec context interface, and the o3 stalls when that occurs. Additionally, these changes don't update the LOCK register and probably break ll/sc. Both o3 changes were removed since a great deal of manual patching would be required to only remove the hwrei change. --- src/arch/alpha/ev5.cc | 50 ++++++++++++++++++++++++++++++++++++++++++ src/arch/alpha/isa/decoder.isa | 34 ++-------------------------- src/arch/alpha/isa/main.isa | 3 --- src/arch/x86/bios/IntelMP.py | 9 -------- 4 files changed, 52 insertions(+), 44 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index c11b3632e..7dc02a611 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -547,3 +547,53 @@ copyIprs(ThreadContext *src, ThreadContext *dest) } } // namespace AlphaISA + +#if FULL_SYSTEM + +using namespace AlphaISA; + +Fault +SimpleThread::hwrei() +{ + if (!(readPC() & 0x3)) + return new UnimplementedOpcodeFault; + + setNextPC(readMiscRegNoEffect(IPR_EXC_ADDR)); + + if (!misspeculating()) { + if (kernelStats) + kernelStats->hwrei(); + } + + // FIXME: XXX check for interrupts? XXX + return NoFault; +} + +/** + * Check for special simulator handling of specific PAL calls. + * If return value is false, actual PAL call will be suppressed. + */ +bool +SimpleThread::simPalCheck(int palFunc) +{ + if (kernelStats) + kernelStats->callpal(palFunc, tc); + + switch (palFunc) { + case PAL::halt: + halt(); + if (--System::numSystemsRunning == 0) + exitSimLoop("all cpus halted"); + break; + + case PAL::bpt: + case PAL::bugchk: + if (system->breakpoint()) + return false; + break; + } + + return true; +} + +#endif // FULL_SYSTEM diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index 06676ae87..270940df2 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -698,28 +698,7 @@ decode OPCODE default Unknown::unknown() { else { // check to see if simulator wants to do something special // on this PAL call (including maybe suppress it) - - bool dopal = true; - - ThreadContext * tc = xc->tcBase(); - AlphaISA::Kernel::Statistics * kernelStats = tc->getKernelStats(); - System * system = tc->getSystemPtr(); - if (kernelStats) - kernelStats->callpal(palFunc, tc); - - switch (palFunc) { - case PAL::halt: - tc->halt(); - if (--System::numSystemsRunning == 0) - exitSimLoop("all cpus halted"); - break; - - case PAL::bpt: - case PAL::bugchk: - if (system->breakpoint()) - dopal = false; - break; - } + bool dopal = xc->simPalCheck(palFunc); if (dopal) { xc->setMiscReg(IPR_EXC_ADDR, NPC); @@ -807,16 +786,7 @@ decode OPCODE default Unknown::unknown() { format BasicOperate { 0x1e: decode PALMODE { 0: OpcdecFault::hw_rei(); - 1: hw_rei({{ - NPC = ExcAddr; - ThreadContext * tc = xc->tcBase(); - if (!tc->misspeculating()) { - AlphaISA::Kernel::Statistics * kernelStats = - tc->getKernelStats(); - if (kernelStats) - kernelStats->hwrei(); - } - }}, IsSerializing, IsSerializeBefore); + 1:hw_rei({{ xc->hwrei(); }}, IsSerializing, IsSerializeBefore); } // M5 special opcodes use the reserved 0x01 opcode space diff --git a/src/arch/alpha/isa/main.isa b/src/arch/alpha/isa/main.isa index 0f7f74359..5231712c8 100644 --- a/src/arch/alpha/isa/main.isa +++ b/src/arch/alpha/isa/main.isa @@ -69,8 +69,6 @@ output exec {{ #include #if FULL_SYSTEM -#include "arch/alpha/kernel_stats.hh" -#include "arch/alpha/osfpal.hh" #include "sim/pseudo_inst.hh" #endif #include "arch/alpha/ipr.hh" @@ -189,7 +187,6 @@ def operands {{ 'Runiq': ('ControlReg', 'uq', 'MISCREG_UNIQ', None, 1), 'FPCR': ('ControlReg', 'uq', 'MISCREG_FPCR', None, 1), 'IntrFlag': ('ControlReg', 'uq', 'MISCREG_INTR', None, 1), - 'ExcAddr': ('ControlReg', 'uq', 'IPR_EXC_ADDR', None, 1), # The next two are hacks for non-full-system call-pal emulation 'R0': ('IntReg', 'uq', '0', None, 1), 'R16': ('IntReg', 'uq', '16', None, 1), diff --git a/src/arch/x86/bios/IntelMP.py b/src/arch/x86/bios/IntelMP.py index 758932180..70e7963fa 100644 --- a/src/arch/x86/bios/IntelMP.py +++ b/src/arch/x86/bios/IntelMP.py @@ -86,15 +86,6 @@ class X86IntelMPConfigTable(SimObject): ext_entries = VectorParam.X86IntelMPExtConfigEntry([], 'extended configuration table entries') - def add_entry(self, entry): - if isinstance(entry, X86IntelMPBaseConfigEntry): - self.base_entries.append(entry) - elif isinstance(entry, X86IntelMPExtConfigEntry): - self.base_entries.append(entry) - else: - panic("Don't know what type of Intel MP entry %s is." \ - % entry.__class__.__name__) - class X86IntelMPBaseConfigEntry(SimObject): type = 'X86IntelMPBaseConfigEntry' cxx_class = 'X86ISA::IntelMP::BaseConfigEntry' -- cgit v1.2.3 From 9836d81c2bba97e36c43ca22feee1d51a12ce6ac Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 21 Oct 2008 07:12:53 -0700 Subject: style: Use the correct m5 style for things relating to interrupts. --- src/arch/alpha/interrupts.hh | 4 ++-- src/arch/mips/interrupts.cc | 6 +++--- src/arch/mips/interrupts.hh | 28 +++++++++++++----------- src/arch/sparc/interrupts.hh | 37 ++++++++++++++++++++------------ src/arch/sparc/miscregfile.cc | 4 ++-- src/arch/sparc/tlb.cc | 8 +++---- src/arch/sparc/ua2005.cc | 32 +++++++++++++-------------- src/arch/x86/interrupts.cc | 10 ++++----- src/arch/x86/interrupts.hh | 50 ++++++++++++++++++++++++------------------- 9 files changed, 98 insertions(+), 81 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/interrupts.hh b/src/arch/alpha/interrupts.hh index e7a451d4d..89db134ff 100644 --- a/src/arch/alpha/interrupts.hh +++ b/src/arch/alpha/interrupts.hh @@ -101,7 +101,7 @@ class Interrupts : public SimObject } void - clear_all() + clearAll() { DPRINTF(Interrupt, "Interrupts all cleared\n"); @@ -124,7 +124,7 @@ class Interrupts : public SimObject } bool - check_interrupts(ThreadContext *tc) const + checkInterrupts(ThreadContext *tc) const { return (intstatus != 0) && !(tc->readPC() & 0x3); } diff --git a/src/arch/mips/interrupts.cc b/src/arch/mips/interrupts.cc index e04d22631..99f96fafc 100755 --- a/src/arch/mips/interrupts.cc +++ b/src/arch/mips/interrupts.cc @@ -76,7 +76,7 @@ static inline void setCauseIP_(ThreadContext *tc, uint8_t val) { intstatus &= ~(1 << int_num); } - void Interrupts::clear_all() + void Interrupts::clearAll() { DPRINTF(Interrupt, "Interrupts all cleared\n"); intstatus = 0; @@ -189,14 +189,14 @@ void Interrupts::clear(int int_num, int index) fatal("Must use Thread COntext when clearing MIPS Interrupts in M5"); } -void Interrupts::clear_all(ThreadContext *tc) +void Interrupts::clearAll(ThreadContext *tc) { DPRINTF(Interrupt, "Interrupts all cleared\n"); uint8_t intstatus = 0; setCauseIP_(tc, intstatus); } -void Interrupts::clear_all() +void Interrupts::clearAll() { fatal("Must use Thread COntext when clearing MIPS Interrupts in M5"); } diff --git a/src/arch/mips/interrupts.hh b/src/arch/mips/interrupts.hh index 99a8f6fa0..af71e4636 100755 --- a/src/arch/mips/interrupts.hh +++ b/src/arch/mips/interrupts.hh @@ -57,23 +57,23 @@ class Interrupts // for posting an interrupt. It sets a bit // in intstatus corresponding to Cause IP*. The // MIPS register Cause is updated by updateIntrInfo - // which is called by check_interrupts + // which is called by checkInterrupts // void post(int int_num, int index); // clear(int int_num, int index) is responsible // for clearing an interrupt. It clear a bit // in intstatus corresponding to Cause IP*. The // MIPS register Cause is updated by updateIntrInfo - // which is called by check_interrupts + // which is called by checkInterrupts // void clear(int int_num, int index); - // clear_all() is responsible + // clearAll() is responsible // for clearing all interrupts. It clears all bits // in intstatus corresponding to Cause IP*. The // MIPS register Cause is updated by updateIntrInfo - // which is called by check_interrupts + // which is called by checkInterrupts // - void clear_all(); + void clearAll(); // getInterrupt(ThreadContext * tc) checks if an interrupt // should be returned. It ands the interrupt mask and @@ -91,7 +91,7 @@ class Interrupts void updateIntrInfoCpuTimerIntr(ThreadContext *tc) const; bool onCpuTimerInterrupt(ThreadContext *tc) const; - bool check_interrupts(ThreadContext * tc) const{ + bool checkInterrupts(ThreadContext *tc) const { //return (intstatus != 0) && !(tc->readPC() & 0x3); if (oncputimerintr == false){ updateIntrInfo(tc); @@ -119,7 +119,7 @@ class Interrupts // for posting an interrupt. It sets a bit // in intstatus corresponding to Cause IP*. The // MIPS register Cause is updated by updateIntrInfo - // which is called by check_interrupts + // which is called by checkInterrupts // void post(int int_num, ThreadContext* tc); void post(int int_num, int index); @@ -128,19 +128,19 @@ class Interrupts // for clearing an interrupt. It clear a bit // in intstatus corresponding to Cause IP*. The // MIPS register Cause is updated by updateIntrInfo - // which is called by check_interrupts + // which is called by checkInterrupts // void clear(int int_num, ThreadContext* tc); void clear(int int_num, int index); - // clear_all() is responsible + // clearAll() is responsible // for clearing all interrupts. It clears all bits // in intstatus corresponding to Cause IP*. The // MIPS register Cause is updated by updateIntrInfo - // which is called by check_interrupts + // which is called by checkInterrupts // - void clear_all(ThreadContext* tc); - void clear_all(); + void clearAll(ThreadContext* tc); + void clearAll(); // getInterrupt(ThreadContext * tc) checks if an interrupt // should be returned. It ands the interrupt mask and @@ -158,7 +158,9 @@ class Interrupts bool interruptsPending(ThreadContext *tc) const; bool onCpuTimerInterrupt(ThreadContext *tc) const; - bool check_interrupts(ThreadContext * tc) const{ + bool + checkInterrupts(ThreadContext *tc) const + { return interruptsPending(tc); } diff --git a/src/arch/sparc/interrupts.hh b/src/arch/sparc/interrupts.hh index 7d1496d8e..66b3792b5 100644 --- a/src/arch/sparc/interrupts.hh +++ b/src/arch/sparc/interrupts.hh @@ -45,7 +45,6 @@ class Interrupts : public SimObject { private: - uint64_t interrupts[NumInterruptTypes]; uint64_t intStatus; @@ -60,10 +59,11 @@ class Interrupts : public SimObject Interrupts(Params * p) : SimObject(p) { - clear_all(); + clearAll(); } - int InterruptLevel(uint64_t softint) + int + InterruptLevel(uint64_t softint) { if (softint & 0x10000 || softint & 0x1) return 14; @@ -76,7 +76,8 @@ class Interrupts : public SimObject return 0; } - void post(int int_num, int index) + void + post(int int_num, int index) { DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); assert(int_num >= 0 && int_num < NumInterruptTypes); @@ -86,7 +87,8 @@ class Interrupts : public SimObject intStatus |= ULL(1) << int_num; } - void clear(int int_num, int index) + void + clear(int int_num, int index) { DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); assert(int_num >= 0 && int_num < NumInterruptTypes); @@ -97,7 +99,8 @@ class Interrupts : public SimObject intStatus &= ~(ULL(1) << int_num); } - void clear_all() + void + clearAll() { for (int i = 0; i < NumInterruptTypes; ++i) { interrupts[i] = 0; @@ -105,12 +108,14 @@ class Interrupts : public SimObject intStatus = 0; } - bool check_interrupts(ThreadContext * tc) const + bool + checkInterrupts(ThreadContext *tc) const { return intStatus; } - Fault getInterrupt(ThreadContext * tc) + Fault + getInterrupt(ThreadContext *tc) { int hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); int pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); @@ -153,8 +158,8 @@ class Interrupts : public SimObject return new DevMondo; } if (interrupts[IT_SOFT_INT]) { - return new - InterruptLevelN(InterruptLevel(interrupts[IT_SOFT_INT])); + int level = InterruptLevel(interrupts[IT_SOFT_INT]); + return new InterruptLevelN(level); } if (interrupts[IT_RES_ERROR]) { @@ -165,24 +170,28 @@ class Interrupts : public SimObject return NoFault; } - void updateIntrInfo(ThreadContext * tc) + void + updateIntrInfo(ThreadContext *tc) { } - uint64_t get_vec(int int_num) + uint64_t + get_vec(int int_num) { assert(int_num >= 0 && int_num < NumInterruptTypes); return interrupts[int_num]; } - void serialize(std::ostream &os) + void + serialize(std::ostream &os) { SERIALIZE_ARRAY(interrupts,NumInterruptTypes); SERIALIZE_SCALAR(intStatus); } - void unserialize(Checkpoint *cp, const std::string §ion) + void + unserialize(Checkpoint *cp, const std::string §ion) { UNSERIALIZE_ARRAY(interrupts,NumInterruptTypes); UNSERIALIZE_SCALAR(intStatus); diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index b0c5dbda9..b22ceb657 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -542,9 +542,9 @@ void MiscRegFile::setReg(int miscReg, tl = val; #if FULL_SYSTEM if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv)) - tc->getCpuPtr()->post_interrupt(IT_TRAP_LEVEL_ZERO,0); + tc->getCpuPtr()->postInterrupt(IT_TRAP_LEVEL_ZERO, 0); else - tc->getCpuPtr()->clear_interrupt(IT_TRAP_LEVEL_ZERO,0); + tc->getCpuPtr()->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0); #endif return; case MISCREG_CWP: diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index 61f0985db..b6a450ffe 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -1021,7 +1021,7 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) dynamic_cast( tc->getCpuPtr()->getInterruptController()); temp = findMsbSet(interrupts->get_vec(IT_INT_VEC)); - tc->getCpuPtr()->clear_interrupt(IT_INT_VEC, temp); + tc->getCpuPtr()->clearInterrupt(IT_INT_VEC, temp); pkt->set(temp); } break; @@ -1268,15 +1268,15 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) SparcISA::Interrupts * interrupts = dynamic_cast( tc->getCpuPtr()->getInterruptController()); - while(interrupts->get_vec(IT_INT_VEC) & data) { + while (interrupts->get_vec(IT_INT_VEC) & data) { msb = findMsbSet(interrupts->get_vec(IT_INT_VEC) & data); - tc->getCpuPtr()->clear_interrupt(IT_INT_VEC, msb); + tc->getCpuPtr()->clearInterrupt(IT_INT_VEC, msb); } } break; case ASI_SWVR_UDB_INTR_W: tc->getSystemPtr()->threadContexts[bits(data,12,8)]->getCpuPtr()-> - post_interrupt(bits(data,5,0),0); + postInterrupt(bits(data, 5, 0), 0); break; default: doMmuWriteError: diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index 7b8524703..e1276b812 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -44,20 +44,20 @@ MiscRegFile::checkSoftInt(ThreadContext *tc) // If PIL < 14, copy over the tm and sm bits if (pil < 14 && softint & 0x10000) - cpu->post_interrupt(IT_SOFT_INT, 16); + cpu->postInterrupt(IT_SOFT_INT, 16); else - cpu->clear_interrupt(IT_SOFT_INT, 16); + cpu->clearInterrupt(IT_SOFT_INT, 16); if (pil < 14 && softint & 0x1) - cpu->post_interrupt(IT_SOFT_INT, 0); + cpu->postInterrupt(IT_SOFT_INT, 0); else - cpu->clear_interrupt(IT_SOFT_INT, 0); + cpu->clearInterrupt(IT_SOFT_INT, 0); // Copy over any of the other bits that are set for (int bit = 15; bit > 0; --bit) { if (1 << bit & softint && bit > pil) - cpu->post_interrupt(IT_SOFT_INT, bit); + cpu->postInterrupt(IT_SOFT_INT, bit); else - cpu->clear_interrupt(IT_SOFT_INT, bit); + cpu->clearInterrupt(IT_SOFT_INT, bit); } } @@ -124,9 +124,9 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) case MISCREG_HINTP: setRegNoEffect(miscReg, val); if (hintp) - cpu->post_interrupt(IT_HINTP, 0); + cpu->postInterrupt(IT_HINTP, 0); else - cpu->clear_interrupt(IT_HINTP, 0); + cpu->clearInterrupt(IT_HINTP, 0); break; case MISCREG_HTBA: @@ -138,25 +138,25 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) case MISCREG_QUEUE_CPU_MONDO_TAIL: setRegNoEffect(miscReg, val); if (cpu_mondo_head != cpu_mondo_tail) - cpu->post_interrupt(IT_CPU_MONDO, 0); + cpu->postInterrupt(IT_CPU_MONDO, 0); else - cpu->clear_interrupt(IT_CPU_MONDO, 0); + cpu->clearInterrupt(IT_CPU_MONDO, 0); break; case MISCREG_QUEUE_DEV_MONDO_HEAD: case MISCREG_QUEUE_DEV_MONDO_TAIL: setRegNoEffect(miscReg, val); if (dev_mondo_head != dev_mondo_tail) - cpu->post_interrupt(IT_DEV_MONDO, 0); + cpu->postInterrupt(IT_DEV_MONDO, 0); else - cpu->clear_interrupt(IT_DEV_MONDO, 0); + cpu->clearInterrupt(IT_DEV_MONDO, 0); break; case MISCREG_QUEUE_RES_ERROR_HEAD: case MISCREG_QUEUE_RES_ERROR_TAIL: setRegNoEffect(miscReg, val); if (res_error_head != res_error_tail) - cpu->post_interrupt(IT_RES_ERROR, 0); + cpu->postInterrupt(IT_RES_ERROR, 0); else - cpu->clear_interrupt(IT_RES_ERROR, 0); + cpu->clearInterrupt(IT_RES_ERROR, 0); break; case MISCREG_QUEUE_NRES_ERROR_HEAD: case MISCREG_QUEUE_NRES_ERROR_TAIL: @@ -185,9 +185,9 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) setRegNoEffect(miscReg, val | HPSTATE::id); #if FULL_SYSTEM if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv)) - cpu->post_interrupt(IT_TRAP_LEVEL_ZERO, 0); + cpu->postInterrupt(IT_TRAP_LEVEL_ZERO, 0); else - cpu->clear_interrupt(IT_TRAP_LEVEL_ZERO, 0); + cpu->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0); #endif break; case MISCREG_HTSTATE: diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index bfb4d5b9c..a16ea5360 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -470,7 +470,7 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val) } bool -X86ISA::Interrupts::check_interrupts(ThreadContext * tc) const +X86ISA::Interrupts::checkInterrupts(ThreadContext *tc) const { RFLAGS rflags = tc->readMiscRegNoEffect(MISCREG_RFLAGS); if (pendingUnmaskableInt) { @@ -492,9 +492,9 @@ X86ISA::Interrupts::check_interrupts(ThreadContext * tc) const } Fault -X86ISA::Interrupts::getInterrupt(ThreadContext * tc) +X86ISA::Interrupts::getInterrupt(ThreadContext *tc) { - assert(check_interrupts(tc)); + assert(checkInterrupts(tc)); // These are all probably fairly uncommon, so we'll make them easier to // check for. if (pendingUnmaskableInt) { @@ -523,9 +523,9 @@ X86ISA::Interrupts::getInterrupt(ThreadContext * tc) } void -X86ISA::Interrupts::updateIntrInfo(ThreadContext * tc) +X86ISA::Interrupts::updateIntrInfo(ThreadContext *tc) { - assert(check_interrupts(tc)); + assert(checkInterrupts(tc)); if (pendingUnmaskableInt) { if (pendingSmi) { DPRINTF(LocalApic, "SMI sent to core.\n"); diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh index a998e2b12..8c7316217 100644 --- a/src/arch/x86/interrupts.hh +++ b/src/arch/x86/interrupts.hh @@ -70,8 +70,7 @@ class ThreadContext; -namespace X86ISA -{ +namespace X86ISA { class Interrupts : public BasicPioDevice, IntDev { @@ -189,7 +188,8 @@ class Interrupts : public BasicPioDevice, IntDev */ typedef X86LocalApicParams Params; - void setClock(Tick newClock) + void + setClock(Tick newClock) { clock = newClock; } @@ -243,7 +243,8 @@ class Interrupts : public BasicPioDevice, IntDev uint32_t readReg(ApicRegIndex miscReg); void setReg(ApicRegIndex reg, uint32_t val); - void setRegNoEffect(ApicRegIndex reg, uint32_t val) + void + setRegNoEffect(ApicRegIndex reg, uint32_t val) { regs[reg] = val; } @@ -252,14 +253,14 @@ class Interrupts : public BasicPioDevice, IntDev * Constructor. */ - Interrupts(Params * p) : BasicPioDevice(p), IntDev(this), - latency(p->pio_latency), clock(0), - apicTimerEvent(this), - pendingSmi(false), smiVector(0), - pendingNmi(false), nmiVector(0), - pendingExtInt(false), extIntVector(0), - pendingInit(false), initVector(0), - pendingUnmaskableInt(false) + Interrupts(Params * p) + : BasicPioDevice(p), IntDev(this), latency(p->pio_latency), clock(0), + apicTimerEvent(this), + pendingSmi(false), smiVector(0), + pendingNmi(false), nmiVector(0), + pendingExtInt(false), extIntVector(0), + pendingInit(false), initVector(0), + pendingUnmaskableInt(false) { pioSize = PageBytes; memset(regs, 0, sizeof(regs)); @@ -273,20 +274,22 @@ class Interrupts : public BasicPioDevice, IntDev * Functions for retrieving interrupts for the CPU to handle. */ - bool check_interrupts(ThreadContext * tc) const; - Fault getInterrupt(ThreadContext * tc); - void updateIntrInfo(ThreadContext * tc); + bool checkInterrupts(ThreadContext *tc) const; + Fault getInterrupt(ThreadContext *tc); + void updateIntrInfo(ThreadContext *tc); /* * Serialization. */ - void serialize(std::ostream & os) + void + serialize(std::ostream &os) { panic("Interrupts::serialize unimplemented!\n"); } - void unserialize(Checkpoint * cp, const std::string & section) + void + unserialize(Checkpoint *cp, const std::string §ion) { panic("Interrupts::unserialize unimplemented!\n"); } @@ -295,22 +298,25 @@ class Interrupts : public BasicPioDevice, IntDev * Old functions needed for compatability but which will be phased out * eventually. */ - void post(int int_num, int index) + void + post(int int_num, int index) { panic("Interrupts::post unimplemented!\n"); } - void clear(int int_num, int index) + void + clear(int int_num, int index) { panic("Interrupts::clear unimplemented!\n"); } - void clear_all() + void + clearAll() { - panic("Interrupts::clear_all unimplemented!\n"); + panic("Interrupts::clearAll unimplemented!\n"); } }; -}; +} // namespace X86ISA #endif // __ARCH_X86_INTERRUPTS_HH__ -- cgit v1.2.3 From c55a467a06eaa59c47c52a2adddc266b8e545589 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Sun, 2 Nov 2008 21:56:57 -0500 Subject: make BaseCPU the provider of _cpuId, and cpuId() instead of being scattered across the subclasses. generally make it so that member data is _cpuId and accessor functions are cpuId(). The ID val comes from the python (default -1 if none provided), and if it is -1, the index of cpuList will be given. this has passed util/regress quick and se.py -n4 and fs.py -n4 as well as standard switch. --- src/arch/alpha/locked_mem.hh | 2 +- src/arch/mips/locked_mem.hh | 2 +- src/arch/sparc/ua2005.cc | 6 +++--- src/arch/x86/tlb.cc | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/locked_mem.hh b/src/arch/alpha/locked_mem.hh index f629d982a..6f4f5a748 100644 --- a/src/arch/alpha/locked_mem.hh +++ b/src/arch/alpha/locked_mem.hh @@ -87,7 +87,7 @@ handleLockedWrite(XC *xc, Request *req) if (stCondFailures % 100000 == 0) { warn("cpu %d: %d consecutive " "store conditional failures\n", - xc->readCpuId(), stCondFailures); + xc->cpuId(), stCondFailures); } // store conditional failed already, so don't issue it to mem diff --git a/src/arch/mips/locked_mem.hh b/src/arch/mips/locked_mem.hh index 07dc9d588..5877b1439 100644 --- a/src/arch/mips/locked_mem.hh +++ b/src/arch/mips/locked_mem.hh @@ -85,7 +85,7 @@ handleLockedWrite(XC *xc, Request *req) if (stCondFailures % 10 == 0) { warn("%i: cpu %d: %d consecutive " "store conditional failures\n", - curTick, xc->readCpuId(), stCondFailures); + curTick, xc->cpuId(), stCondFailures); } if (stCondFailures == 5000) { diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index e1276b812..6961a24e9 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -257,11 +257,11 @@ MiscRegFile::readFSReg(int miscReg, ThreadContext * tc) temp = readRegNoEffect(miscReg) & (STS::active | STS::speculative); // Check that the CPU array is fully populated // (by calling getNumCPus()) - assert(sys->getNumCPUs() > tc->readCpuId()); + assert(sys->getNumCPUs() > tc->cpuId()); - temp |= tc->readCpuId() << STS::shft_id; + temp |= tc->cpuId() << STS::shft_id; - for (x = tc->readCpuId() & ~3; x < sys->threadContexts.size(); x++) { + for (x = tc->cpuId() & ~3; x < sys->threadContexts.size(); x++) { switch (sys->threadContexts[x]->status()) { case ThreadContext::Active: temp |= STS::st_run << (STS::shft_fsm0 - diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 5db678919..17374fa0c 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -654,7 +654,7 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) */ // Force the access to be uncacheable. req->setFlags(req->getFlags() | UNCACHEABLE); - req->setPaddr(x86LocalAPICAddress(tc->readCpuId(), paddr - baseAddr)); + req->setPaddr(x86LocalAPICAddress(tc->cpuId(), paddr - baseAddr)); } #endif return NoFault; -- cgit v1.2.3 From 67fda02dda290d614de233846fee434b3713b1dc Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Sun, 2 Nov 2008 21:57:06 -0500 Subject: Make it so that all thread contexts are registered with the System, even in SE. Process still keeps track of the tc's it owns, but registration occurs with the System, this eases the way for system-wide context Ids based on registration. --- src/arch/alpha/process.cc | 11 +++++----- src/arch/sparc/process.cc | 54 +++++++++++++++++++++++++---------------------- src/arch/x86/process.cc | 11 +++++----- 3 files changed, 41 insertions(+), 35 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc index 380e0e18e..28e8df308 100644 --- a/src/arch/alpha/process.cc +++ b/src/arch/alpha/process.cc @@ -67,12 +67,13 @@ AlphaLiveProcess::startup() argsInit(MachineBytes, VMPageSize); - threadContexts[0]->setIntReg(GlobalPointerReg, objFile->globalPointer()); - //Opperate in user mode - threadContexts[0]->setMiscRegNoEffect(IPR_ICM, 0x18); + ThreadContext *tc = system->getThreadContext(contextIds[0]); + tc->setIntReg(GlobalPointerReg, objFile->globalPointer()); + //Operate in user mode + tc->setMiscRegNoEffect(IPR_ICM, 0x18); //No super page mapping - threadContexts[0]->setMiscRegNoEffect(IPR_MCSR, 0); + tc->setMiscRegNoEffect(IPR_MCSR, 0); //Set this to 0 for now, but it should be unique for each process - threadContexts[0]->setMiscRegNoEffect(IPR_DTB_ASN, M5_pid << 57); + tc->setMiscRegNoEffect(IPR_DTB_ASN, M5_pid << 57); } diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index a8fda04eb..987e0465e 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -112,44 +112,45 @@ SparcLiveProcess::startup() { Process::startup(); + ThreadContext *tc = system->getThreadContext(contextIds[0]); //From the SPARC ABI //Setup default FP state - threadContexts[0]->setMiscRegNoEffect(MISCREG_FSR, 0); + tc->setMiscRegNoEffect(MISCREG_FSR, 0); - threadContexts[0]->setMiscRegNoEffect(MISCREG_TICK, 0); + tc->setMiscRegNoEffect(MISCREG_TICK, 0); /* * Register window management registers */ //No windows contain info from other programs - //threadContexts[0]->setMiscRegNoEffect(MISCREG_OTHERWIN, 0); - threadContexts[0]->setIntReg(NumIntArchRegs + 6, 0); + //tc->setMiscRegNoEffect(MISCREG_OTHERWIN, 0); + tc->setIntReg(NumIntArchRegs + 6, 0); //There are no windows to pop - //threadContexts[0]->setMiscRegNoEffect(MISCREG_CANRESTORE, 0); - threadContexts[0]->setIntReg(NumIntArchRegs + 4, 0); + //tc->setMiscRegNoEffect(MISCREG_CANRESTORE, 0); + tc->setIntReg(NumIntArchRegs + 4, 0); //All windows are available to save into - //threadContexts[0]->setMiscRegNoEffect(MISCREG_CANSAVE, NWindows - 2); - threadContexts[0]->setIntReg(NumIntArchRegs + 3, NWindows - 2); + //tc->setMiscRegNoEffect(MISCREG_CANSAVE, NWindows - 2); + tc->setIntReg(NumIntArchRegs + 3, NWindows - 2); //All windows are "clean" - //threadContexts[0]->setMiscRegNoEffect(MISCREG_CLEANWIN, NWindows); - threadContexts[0]->setIntReg(NumIntArchRegs + 5, NWindows); + //tc->setMiscRegNoEffect(MISCREG_CLEANWIN, NWindows); + tc->setIntReg(NumIntArchRegs + 5, NWindows); //Start with register window 0 - threadContexts[0]->setMiscRegNoEffect(MISCREG_CWP, 0); + tc->setMiscRegNoEffect(MISCREG_CWP, 0); //Always use spill and fill traps 0 - //threadContexts[0]->setMiscRegNoEffect(MISCREG_WSTATE, 0); - threadContexts[0]->setIntReg(NumIntArchRegs + 7, 0); + //tc->setMiscRegNoEffect(MISCREG_WSTATE, 0); + tc->setIntReg(NumIntArchRegs + 7, 0); //Set the trap level to 0 - threadContexts[0]->setMiscRegNoEffect(MISCREG_TL, 0); + tc->setMiscRegNoEffect(MISCREG_TL, 0); //Set the ASI register to something fixed - threadContexts[0]->setMiscRegNoEffect(MISCREG_ASI, ASI_PRIMARY); + tc->setMiscRegNoEffect(MISCREG_ASI, ASI_PRIMARY); /* * T1 specific registers */ //Turn on the icache, dcache, dtb translation, and itb translation. - threadContexts[0]->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL, 15); + tc->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL, 15); } void @@ -160,8 +161,9 @@ Sparc32LiveProcess::startup() SparcLiveProcess::startup(); + ThreadContext *tc = system->getThreadContext(contextIds[0]); //The process runs in user mode with 32 bit addresses - threadContexts[0]->setMiscReg(MISCREG_PSTATE, 0x0a); + tc->setMiscReg(MISCREG_PSTATE, 0x0a); argsInit(32 / 8, VMPageSize); } @@ -174,8 +176,9 @@ Sparc64LiveProcess::startup() SparcLiveProcess::startup(); + ThreadContext *tc = system->getThreadContext(contextIds[0]); //The process runs in user mode - threadContexts[0]->setMiscReg(MISCREG_PSTATE, 0x02); + tc->setMiscReg(MISCREG_PSTATE, 0x02); argsInit(sizeof(IntReg), VMPageSize); } @@ -391,20 +394,21 @@ SparcLiveProcess::argsInit(int pageSize) fillStart = stack_base; spillStart = fillStart + sizeof(MachInst) * numFillInsts; + ThreadContext *tc = system->getThreadContext(contextIds[0]); //Set up the thread context to start running the process //assert(NumArgumentRegs >= 2); - //threadContexts[0]->setIntReg(ArgumentReg[0], argc); - //threadContexts[0]->setIntReg(ArgumentReg[1], argv_array_base); - threadContexts[0]->setIntReg(StackPointerReg, stack_min - StackBias); + //tc->setIntReg(ArgumentReg[0], argc); + //tc->setIntReg(ArgumentReg[1], argv_array_base); + tc->setIntReg(StackPointerReg, stack_min - StackBias); // %g1 is a pointer to a function that should be run at exit. Since we // don't have anything like that, it should be set to 0. - threadContexts[0]->setIntReg(1, 0); + tc->setIntReg(1, 0); Addr prog_entry = objFile->entryPoint(); - threadContexts[0]->setPC(prog_entry); - threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst)); - threadContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst))); + tc->setPC(prog_entry); + tc->setNextPC(prog_entry + sizeof(MachInst)); + tc->setNextNPC(prog_entry + (2 * sizeof(MachInst))); //Align the "stack_min" to a page boundary. stack_min = roundDown(stack_min, pageSize); diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index b62efd3cd..52933b7f4 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -146,8 +146,8 @@ X86LiveProcess::startup() argsInit(sizeof(IntReg), VMPageSize); - for (int i = 0; i < threadContexts.size(); i++) { - ThreadContext * tc = threadContexts[i]; + for (int i = 0; i < contextIds.size(); i++) { + ThreadContext * tc = system->getThreadContext(contextIds[i]); SegAttr dataAttr = 0; dataAttr.writable = 1; @@ -458,14 +458,15 @@ X86LiveProcess::argsInit(int intSize, int pageSize) initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize); + ThreadContext *tc = system->getThreadContext(contextIds[0]); //Set the stack pointer register - threadContexts[0]->setIntReg(StackPointerReg, stack_min); + tc->setIntReg(StackPointerReg, stack_min); Addr prog_entry = objFile->entryPoint(); // There doesn't need to be any segment base added in since we're dealing // with the flat segmentation model. - threadContexts[0]->setPC(prog_entry); - threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst)); + tc->setPC(prog_entry); + tc->setNextPC(prog_entry + sizeof(MachInst)); //Align the "stack_min" to a page boundary. stack_min = roundDown(stack_min, pageSize); -- cgit v1.2.3 From d857faf073895dcfde97141bd6346fe5d4317f8e Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Sun, 2 Nov 2008 21:57:07 -0500 Subject: Add in Context IDs to the simulator. From now on, cpuId is almost never used, the primary identifier for a hardware context should be contextId(). The concept of threads within a CPU remains, in the form of threadId() because sometimes you need to know which context within a cpu to manipulate. --- src/arch/alpha/locked_mem.hh | 4 ++-- src/arch/mips/locked_mem.hh | 4 ++-- src/arch/sparc/ua2005.cc | 6 +++--- src/arch/x86/tlb.cc | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/locked_mem.hh b/src/arch/alpha/locked_mem.hh index 6f4f5a748..e8928ba08 100644 --- a/src/arch/alpha/locked_mem.hh +++ b/src/arch/alpha/locked_mem.hh @@ -85,9 +85,9 @@ handleLockedWrite(XC *xc, Request *req) stCondFailures++; xc->setStCondFailures(stCondFailures); if (stCondFailures % 100000 == 0) { - warn("cpu %d: %d consecutive " + warn("context %d: %d consecutive " "store conditional failures\n", - xc->cpuId(), stCondFailures); + xc->contextId(), stCondFailures); } // store conditional failed already, so don't issue it to mem diff --git a/src/arch/mips/locked_mem.hh b/src/arch/mips/locked_mem.hh index 5877b1439..9f41ba075 100644 --- a/src/arch/mips/locked_mem.hh +++ b/src/arch/mips/locked_mem.hh @@ -83,9 +83,9 @@ handleLockedWrite(XC *xc, Request *req) stCondFailures++; xc->setStCondFailures(stCondFailures); if (stCondFailures % 10 == 0) { - warn("%i: cpu %d: %d consecutive " + warn("%i: context %d: %d consecutive " "store conditional failures\n", - curTick, xc->cpuId(), stCondFailures); + curTick, xc->contextId(), stCondFailures); } if (stCondFailures == 5000) { diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index 6961a24e9..502033d97 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -257,11 +257,11 @@ MiscRegFile::readFSReg(int miscReg, ThreadContext * tc) temp = readRegNoEffect(miscReg) & (STS::active | STS::speculative); // Check that the CPU array is fully populated // (by calling getNumCPus()) - assert(sys->getNumCPUs() > tc->cpuId()); + assert(sys->getNumContexts() > tc->contextId()); - temp |= tc->cpuId() << STS::shft_id; + temp |= tc->contextId() << STS::shft_id; - for (x = tc->cpuId() & ~3; x < sys->threadContexts.size(); x++) { + for (x = tc->contextId() & ~3; x < sys->threadContexts.size(); x++) { switch (sys->threadContexts[x]->status()) { case ThreadContext::Active: temp |= STS::st_run << (STS::shft_fsm0 - diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 17374fa0c..4980c5fe5 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -654,7 +654,7 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) */ // Force the access to be uncacheable. req->setFlags(req->getFlags() | UNCACHEABLE); - req->setPaddr(x86LocalAPICAddress(tc->cpuId(), paddr - baseAddr)); + req->setPaddr(x86LocalAPICAddress(tc->contextId(), paddr - baseAddr)); } #endif return NoFault; -- cgit v1.2.3 From dd99ff23c6a71f7173014b5008d0cf12b7ef223a Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Tue, 4 Nov 2008 11:35:42 -0500 Subject: get rid of all instances of readTid() and getThreadNum(). Unify and eliminate redundancies with threadId() as their replacement. --- src/arch/mips/isa/formats/mt.isa | 4 ++-- src/arch/mips/locked_mem.hh | 6 +++--- src/arch/mips/mt.hh | 8 ++++---- src/arch/mips/utility.cc | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src/arch') diff --git a/src/arch/mips/isa/formats/mt.isa b/src/arch/mips/isa/formats/mt.isa index 81fdc2898..1928ee903 100644 --- a/src/arch/mips/isa/formats/mt.isa +++ b/src/arch/mips/isa/formats/mt.isa @@ -196,7 +196,7 @@ def format MT_Control(code, *opt_flags) {{ def format MT_MFTR(code, *flags) {{ flags += ('IsNonSpeculative', ) -# code = 'std::cerr << curTick << \": T\" << xc->tcBase()->getThreadNum() << \": Executing MT INST: ' + name + '\" << endl;\n' + code +# code = 'std::cerr << curTick << \": T\" << xc->tcBase()->threadId() << \": Executing MT INST: ' + name + '\" << endl;\n' + code code += 'if (MT_H == 1) {\n' code += 'data = bits(data, top_bit, bottom_bit);\n' @@ -212,7 +212,7 @@ def format MT_MFTR(code, *flags) {{ def format MT_MTTR(code, *flags) {{ flags += ('IsNonSpeculative', ) -# code = 'std::cerr << curTick << \": T\" << xc->tcBase()->getThreadNum() << \": Executing MT INST: ' + name + '\" << endl;\n' + code +# code = 'std::cerr << curTick << \": T\" << xc->tcBase()->threadId() << \": Executing MT INST: ' + name + '\" << endl;\n' + code iop = InstObjParams(name, Name, 'MTOp', code, flags) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) diff --git a/src/arch/mips/locked_mem.hh b/src/arch/mips/locked_mem.hh index 9f41ba075..021b8cf73 100644 --- a/src/arch/mips/locked_mem.hh +++ b/src/arch/mips/locked_mem.hh @@ -52,7 +52,7 @@ handleLockedRead(XC *xc, Request *req) xc->setMiscRegNoEffect(LLAddr, req->getPaddr() & ~0xf); xc->setMiscRegNoEffect(LLFlag, true); DPRINTF(LLSC, "[tid:%i]: Load-Link Flag Set & Load-Link Address set to %x.\n", - req->getThreadNum(), req->getPaddr() & ~0xf); + req->threadId(), req->getPaddr() & ~0xf); } @@ -94,10 +94,10 @@ handleLockedWrite(XC *xc, Request *req) if (!lock_flag){ DPRINTF(LLSC, "[tid:%i]: Lock Flag Set, Store Conditional Failed.\n", - req->getThreadNum()); + req->threadId()); } else if ((req->getPaddr() & ~0xf) != lock_addr) { DPRINTF(LLSC, "[tid:%i]: Load-Link Address Mismatch, Store Conditional Failed.\n", - req->getThreadNum()); + req->threadId()); } // store conditional failed already, so don't issue it to mem return false; diff --git a/src/arch/mips/mt.hh b/src/arch/mips/mt.hh index 20658df28..8828a09a5 100755 --- a/src/arch/mips/mt.hh +++ b/src/arch/mips/mt.hh @@ -78,7 +78,7 @@ haltThread(TC *tc) // @TODO: Needs to check if this is a branch and if so, take previous instruction tc->setMiscReg(TCRestart, tc->readNextPC()); - warn("%i: Halting thread %i in %s @ PC %x, setting restart PC to %x", curTick, tc->getThreadNum(), tc->getCpuPtr()->name(), + warn("%i: Halting thread %i in %s @ PC %x, setting restart PC to %x", curTick, tc->threadId(), tc->getCpuPtr()->name(), tc->readPC(), tc->readNextPC()); } } @@ -98,7 +98,7 @@ restoreThread(TC *tc) tc->setNextNPC(pc + 8); tc->activate(0); - warn("%i: Restoring thread %i in %s @ PC %x", curTick, tc->getThreadNum(), tc->getCpuPtr()->name(), + warn("%i: Restoring thread %i in %s @ PC %x", curTick, tc->threadId(), tc->getCpuPtr()->name(), tc->readPC()); } } @@ -217,7 +217,7 @@ yieldThread(TC *tc, Fault &fault, int src_reg, uint32_t yield_mask) if (ok == 1) { unsigned tcstatus = tc->readMiscRegNoEffect(TCStatus); tc->setMiscReg(TCStatus, insertBits(tcstatus, TCS_A, TCS_A, 0)); - warn("%i: Deactivating Hardware Thread Context #%i", curTick, tc->getThreadNum()); + warn("%i: Deactivating Hardware Thread Context #%i", curTick, tc->threadId()); } } else if (src_reg > 0) { if (src_reg && !yield_mask != 0) { @@ -238,7 +238,7 @@ yieldThread(TC *tc, Fault &fault, int src_reg, uint32_t yield_mask) fault = new ThreadFault(); } else { //tc->ScheduleOtherThreads(); - //std::cerr << "T" << tc->getThreadNum() << "YIELD: Schedule Other Threads.\n" << std::endl; + //std::cerr << "T" << tc->threadId() << "YIELD: Schedule Other Threads.\n" << std::endl; //tc->suspend(); // Save last known PC in TCRestart // @TODO: Needs to check if this is a branch and if so, take previous instruction diff --git a/src/arch/mips/utility.cc b/src/arch/mips/utility.cc index 1985c0f43..5908caf68 100644 --- a/src/arch/mips/utility.cc +++ b/src/arch/mips/utility.cc @@ -259,7 +259,7 @@ zeroRegisters(CPU *cpu) void startupCPU(ThreadContext *tc, int cpuId) { - tc->activate(0/*tc->getThreadNum()*/); + tc->activate(0/*tc->threadId()*/); } } // namespace MipsISA -- cgit v1.2.3 From 44839d6b716f2eb25eabc57fe588a129e290e51c Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Wed, 5 Nov 2008 07:20:03 -0800 Subject: Fix a few more places where the context stuff wasn't changed --- src/arch/sparc/ua2005.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index 502033d97..2389c963d 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -257,7 +257,7 @@ MiscRegFile::readFSReg(int miscReg, ThreadContext * tc) temp = readRegNoEffect(miscReg) & (STS::active | STS::speculative); // Check that the CPU array is fully populated // (by calling getNumCPus()) - assert(sys->getNumContexts() > tc->contextId()); + assert(sys->numContexts() > tc->contextId()); temp |= tc->contextId() << STS::shft_id; -- cgit v1.2.3 From 8c15518f30a5e7ffe0f82acde714c11000bc3714 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 9 Nov 2008 21:55:43 -0800 Subject: X86: Fix completeAcc get call. --- src/arch/x86/insts/microldstop.hh | 20 ++++++++++++++++++++ src/arch/x86/isa/microops/ldstop.isa | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/insts/microldstop.hh b/src/arch/x86/insts/microldstop.hh index 5b1210d69..eccd37dc2 100644 --- a/src/arch/x86/insts/microldstop.hh +++ b/src/arch/x86/insts/microldstop.hh @@ -59,6 +59,7 @@ #define __ARCH_X86_INSTS_MICROLDSTOP_HH__ #include "arch/x86/insts/microop.hh" +#include "mem/packet.hh" namespace X86ISA { @@ -149,6 +150,25 @@ namespace X86ISA } return fault; } + + uint64_t + get(PacketPtr pkt) const + { + switch(dataSize) + { + case 1: + return pkt->get(); + case 2: + return pkt->get(); + case 4: + return pkt->get(); + case 8: + return pkt->get(); + default: + panic("Bad operand size %d for read at %#x.\n", + dataSize, pkt->getAddr()); + } + } }; } diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index cb63e7cd9..30a7c8801 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -194,7 +194,7 @@ def template MicroLoadCompleteAcc {{ %(op_decl)s; %(op_rd)s; - Mem = pkt->get(); + Mem = get(pkt); %(code)s; -- cgit v1.2.3 From 9c49bc7b00aa24b0488a83039ae8762d8f8094c5 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 10 Nov 2008 11:51:17 -0800 Subject: mem: update stuff for changes to Packet and Request --- src/arch/alpha/faults.cc | 2 +- src/arch/alpha/faults.hh | 14 +++++++------- src/arch/alpha/isa/mem.isa | 7 ++++--- src/arch/alpha/isa/pal.isa | 10 +++++----- src/arch/alpha/tlb.cc | 12 ++++++------ src/arch/mips/isa/formats/mem.isa | 6 +++--- src/arch/mips/isa/formats/util.isa | 3 ++- src/arch/mips/tlb.cc | 2 +- src/arch/sparc/isa/formats/mem/swap.isa | 3 +++ src/arch/sparc/tlb.cc | 6 +++--- src/arch/x86/intmessage.hh | 2 +- src/arch/x86/pagetable_walker.cc | 13 ++++++------- src/arch/x86/tlb.cc | 2 +- 13 files changed, 43 insertions(+), 39 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc index dae188839..e89cf5c64 100644 --- a/src/arch/alpha/faults.cc +++ b/src/arch/alpha/faults.cc @@ -144,7 +144,7 @@ DtbFault::invoke(ThreadContext *tc) // read, like the EV5). The EV6 approach is cleaner and seems to // work with EV5 PAL code, but not the other way around. if (!tc->misspeculating() && - !(reqFlags & VPTE) && !(reqFlags & NO_FAULT)) { + reqFlags.none(Request::VPTE|Request::NO_FAULT)) { // set VA register with faulting address tc->setMiscRegNoEffect(IPR_VA, vaddr); diff --git a/src/arch/alpha/faults.hh b/src/arch/alpha/faults.hh index 4b107273b..9d90c7719 100644 --- a/src/arch/alpha/faults.hh +++ b/src/arch/alpha/faults.hh @@ -140,11 +140,11 @@ class DtbFault : public AlphaFault { protected: VAddr vaddr; - uint32_t reqFlags; + Request::Flags reqFlags; uint64_t flags; public: - DtbFault(VAddr _vaddr, uint32_t _reqFlags, uint64_t _flags) + DtbFault(VAddr _vaddr, Request::Flags _reqFlags, uint64_t _flags) : vaddr(_vaddr), reqFlags(_reqFlags), flags(_flags) { } FaultName name() const = 0; @@ -163,7 +163,7 @@ class NDtbMissFault : public DtbFault static FaultStat _count; public: - NDtbMissFault(VAddr vaddr, uint32_t reqFlags, uint64_t flags) + NDtbMissFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) { } FaultName name() const {return _name;} @@ -182,7 +182,7 @@ class PDtbMissFault : public DtbFault static FaultStat _count; public: - PDtbMissFault(VAddr vaddr, uint32_t reqFlags, uint64_t flags) + PDtbMissFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) { } FaultName name() const {return _name;} @@ -198,7 +198,7 @@ class DtbPageFault : public DtbFault static FaultStat _count; public: - DtbPageFault(VAddr vaddr, uint32_t reqFlags, uint64_t flags) + DtbPageFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) { } FaultName name() const {return _name;} @@ -214,7 +214,7 @@ class DtbAcvFault : public DtbFault static FaultStat _count; public: - DtbAcvFault(VAddr vaddr, uint32_t reqFlags, uint64_t flags) + DtbAcvFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) { } FaultName name() const {return _name;} @@ -230,7 +230,7 @@ class DtbAlignmentFault : public DtbFault static FaultStat _count; public: - DtbAlignmentFault(VAddr vaddr, uint32_t reqFlags, uint64_t flags) + DtbAlignmentFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) { } FaultName name() const {return _name;} diff --git a/src/arch/alpha/isa/mem.isa b/src/arch/alpha/isa/mem.isa index fe0daf772..b4e10e849 100644 --- a/src/arch/alpha/isa/mem.isa +++ b/src/arch/alpha/isa/mem.isa @@ -43,7 +43,7 @@ output header {{ protected: /// Memory request flags. See mem_req_base.hh. - unsigned memAccessFlags; + Request::Flags memAccessFlags; /// Pointer to EAComp object. const StaticInstPtr eaCompPtr; /// Pointer to MemAcc object. @@ -54,7 +54,7 @@ output header {{ StaticInstPtr _eaCompPtr = nullStaticInstPtr, StaticInstPtr _memAccPtr = nullStaticInstPtr) : AlphaStaticInst(mnem, _machInst, __opClass), - memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr) + eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr) { } @@ -677,7 +677,8 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, inst_flags) if mem_flags: - s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' + mem_flags = [ 'Request::%s' % flag for flag in mem_flags ] + s = '\n\tmemAccessFlags.reset(' + string.join(mem_flags, '|') + ');' iop.constructor += s memacc_iop.constructor += s diff --git a/src/arch/alpha/isa/pal.isa b/src/arch/alpha/isa/pal.isa index 294b92e2f..3d3b81600 100644 --- a/src/arch/alpha/isa/pal.isa +++ b/src/arch/alpha/isa/pal.isa @@ -174,11 +174,11 @@ output decoder {{ : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), disp(HW_LDST_DISP) { - memAccessFlags = 0; - if (HW_LDST_PHYS) memAccessFlags |= PHYSICAL; - if (HW_LDST_ALT) memAccessFlags |= ALTMODE; - if (HW_LDST_VPTE) memAccessFlags |= VPTE; - if (HW_LDST_LOCK) memAccessFlags |= LOCKED; + memAccessFlags.clear(); + if (HW_LDST_PHYS) memAccessFlags.set(Request::PHYSICAL); + if (HW_LDST_ALT) memAccessFlags.set(Request::ALTMODE); + if (HW_LDST_VPTE) memAccessFlags.set(Request::VPTE); + if (HW_LDST_LOCK) memAccessFlags.set(Request::LOCKED); } std::string diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc index 9266b8337..be02293d6 100644 --- a/src/arch/alpha/tlb.cc +++ b/src/arch/alpha/tlb.cc @@ -142,7 +142,7 @@ TLB::checkCacheability(RequestPtr &req, bool itb) return new UnimpFault("IPR memory space not implemented!"); } else { // mark request as uncacheable - req->setFlags(req->getFlags() | UNCACHEABLE); + req->setFlags(Request::UNCACHEABLE); #if !ALPHA_TLASER // Clear bits 42:35 of the physical address (10-2 in @@ -321,7 +321,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) { //If this is a pal pc, then set PHYSICAL if (FULL_SYSTEM && PcPAL(req->getPC())) - req->setFlags(req->getFlags() | PHYSICAL); + req->setFlags(Request::PHYSICAL); if (PcPAL(req->getPC())) { // strip off PAL PC marker (lsb is 1) @@ -330,7 +330,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) return NoFault; } - if (req->getFlags() & PHYSICAL) { + if (req->getFlags() & Request::PHYSICAL) { req->setPaddr(req->getVaddr()); } else { // verify that this is a good virtual address @@ -497,13 +497,13 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) } if (PcPAL(pc)) { - mode = (req->getFlags() & ALTMODE) ? + mode = (req->getFlags() & Request::ALTMODE) ? (mode_type)ALT_MODE_AM( tc->readMiscRegNoEffect(IPR_ALT_MODE)) : mode_kernel; } - if (req->getFlags() & PHYSICAL) { + if (req->getFlags() & Request::PHYSICAL) { req->setPaddr(req->getVaddr()); } else { // verify that this is a good virtual address @@ -560,7 +560,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) if (write) { write_misses++; } else { read_misses++; } uint64_t flags = (write ? MM_STAT_WR_MASK : 0) | MM_STAT_DTB_MISS_MASK; - return (req->getFlags() & VPTE) ? + return (req->getFlags() & Request::VPTE) ? (Fault)(new PDtbMissFault(req->getVaddr(), req->getFlags(), flags)) : (Fault)(new NDtbMissFault(req->getVaddr(), req->getFlags(), diff --git a/src/arch/mips/isa/formats/mem.isa b/src/arch/mips/isa/formats/mem.isa index f0210c29b..8596308e2 100644 --- a/src/arch/mips/isa/formats/mem.isa +++ b/src/arch/mips/isa/formats/mem.isa @@ -43,7 +43,7 @@ output header {{ protected: /// Memory request flags. See mem_req_base.hh. - unsigned memAccessFlags; + Request::Flags memAccessFlags; /// Pointer to EAComp object. const StaticInstPtr eaCompPtr; /// Pointer to MemAcc object. @@ -57,7 +57,7 @@ output header {{ StaticInstPtr _eaCompPtr = nullStaticInstPtr, StaticInstPtr _memAccPtr = nullStaticInstPtr) : MipsStaticInst(mnem, _machInst, __opClass), - memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr), + eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr), disp(sext<16>(OFFSET)) { } @@ -70,7 +70,7 @@ output header {{ const StaticInstPtr &eaCompInst() const { return eaCompPtr; } const StaticInstPtr &memAccInst() const { return memAccPtr; } - unsigned memAccFlags() { return memAccessFlags; } + Request::Flags memAccFlags() { return memAccessFlags; } }; /** diff --git a/src/arch/mips/isa/formats/util.isa b/src/arch/mips/isa/formats/util.isa index 0405aa5b3..786a964d4 100644 --- a/src/arch/mips/isa/formats/util.isa +++ b/src/arch/mips/isa/formats/util.isa @@ -61,7 +61,8 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, inst_flags) if mem_flags: - s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' + mem_flags = [ 'Request::%s' % flag for flag in mem_flags ] + s = '\n\tmemAccessFlags.reset(' + string.join(mem_flags, '|') + ');' iop.constructor += s memacc_iop.constructor += s diff --git a/src/arch/mips/tlb.cc b/src/arch/mips/tlb.cc index 7c3b6aed5..e91da4eea 100644 --- a/src/arch/mips/tlb.cc +++ b/src/arch/mips/tlb.cc @@ -149,7 +149,7 @@ TLB::checkCacheability(RequestPtr &req) // or by the TLB entry if((req->getVaddr() & VAddrUncacheable) == VAddrUncacheable) { // mark request as uncacheable - req->setFlags(req->getFlags() | UNCACHEABLE); + req->setFlags(Request::UNCACHEABLE); } return NoFault; } diff --git a/src/arch/sparc/isa/formats/mem/swap.isa b/src/arch/sparc/isa/formats/mem/swap.isa index 2ebe9aa15..046f89822 100644 --- a/src/arch/sparc/isa/formats/mem/swap.isa +++ b/src/arch/sparc/isa/formats/mem/swap.isa @@ -133,6 +133,7 @@ let {{ def format Swap(code, postacc_code, mem_flags, *opt_flags) {{ mem_flags = makeList(mem_flags) + mem_flags = [ 'Request::%s' % flag for flag in mem_flags ] flags = string.join(mem_flags, '|') (header_output, @@ -144,6 +145,7 @@ def format Swap(code, postacc_code, mem_flags, *opt_flags) {{ def format SwapAlt(code, postacc_code, mem_flags, *opt_flags) {{ mem_flags = makeList(mem_flags) + mem_flags = [ 'Request::%s' % flag for flag in mem_flags ] mem_flags.append("EXT_ASI") flags = string.join(mem_flags, '|') (header_output, @@ -175,6 +177,7 @@ let {{ def format CasAlt(code, postacc_code, mem_flags, *opt_flags) {{ mem_flags = makeList(mem_flags) + mem_flags = [ 'Request::%s' % flag for flag in mem_flags ] mem_flags.append("EXT_ASI") flags = string.join(mem_flags, '|') (header_output, diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index b6a450ffe..875ae1411 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -594,7 +594,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) (!write || ce->pte.writable())) { req->setPaddr(ce->pte.translate(vaddr)); if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1) - req->setFlags(req->getFlags() | UNCACHEABLE); + req->setFlags(Request::UNCACHEABLE); DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); return NoFault; } // if matched @@ -607,7 +607,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) (!write || ce->pte.writable())) { req->setPaddr(ce->pte.translate(vaddr)); if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1) - req->setFlags(req->getFlags() | UNCACHEABLE); + req->setFlags(Request::UNCACHEABLE); DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); return NoFault; } // if matched @@ -769,7 +769,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) } if (e->pte.sideffect() || (e->pte.paddr() >> 39) & 1) - req->setFlags(req->getFlags() | UNCACHEABLE); + req->setFlags(Request::UNCACHEABLE); // cache translation date for next translation cacheState = tlbdata; diff --git a/src/arch/x86/intmessage.hh b/src/arch/x86/intmessage.hh index 6a5b3aa30..f5f8519e2 100644 --- a/src/arch/x86/intmessage.hh +++ b/src/arch/x86/intmessage.hh @@ -78,7 +78,7 @@ namespace X86ISA prepIntRequest(const uint8_t id, Addr offset, Addr size) { RequestPtr req = new Request(x86InterruptAddress(id, offset), - size, UNCACHEABLE); + size, Request::UNCACHEABLE); PacketPtr pkt = new Packet(req, MemCmd::MessageReq, Packet::Broadcast); pkt->allocate(); return pkt; diff --git a/src/arch/x86/pagetable_walker.cc b/src/arch/x86/pagetable_walker.cc index e70c16b1d..564a04b38 100644 --- a/src/arch/x86/pagetable_walker.cc +++ b/src/arch/x86/pagetable_walker.cc @@ -298,11 +298,8 @@ Walker::doNext(PacketPtr &read, PacketPtr &write) } PacketPtr oldRead = read; //If we didn't return, we're setting up another read. - uint32_t flags = oldRead->req->getFlags(); - if (uncacheable) - flags |= UNCACHEABLE; - else - flags &= ~UNCACHEABLE; + Request::Flags flags = oldRead->req->getFlags(); + flags.set(Request::UNCACHEABLE, uncacheable); RequestPtr request = new Request(nextRead, oldRead->getSize(), flags); read = new Packet(request, MemCmd::ReadExReq, Packet::Broadcast); @@ -365,8 +362,10 @@ Walker::start(ThreadContext * _tc, Addr vaddr) enableNX = efer.nxe; - RequestPtr request = - new Request(top, size, PHYSICAL | cr3.pcd ? UNCACHEABLE : 0); + Request::Flags flags = Request::PHYSICAL; + if (cr3.pcd) + flags.set(Request::UNCACHEABLE); + RequestPtr request = new Request(top, size, flags); read = new Packet(request, MemCmd::ReadExReq, Packet::Broadcast); read->allocate(); Enums::MemoryMode memMode = sys->getMemoryMode(); diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 4980c5fe5..6f1c1a03c 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -653,7 +653,7 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) return new GeneralProtection(0); */ // Force the access to be uncacheable. - req->setFlags(req->getFlags() | UNCACHEABLE); + req->setFlags(Request::UNCACHEABLE); req->setPaddr(x86LocalAPICAddress(tc->contextId(), paddr - baseAddr)); } #endif -- cgit v1.2.3 From eb5d9ba72b0309e7f98c382e3a80ce0601dbe084 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 10 Nov 2008 11:51:18 -0800 Subject: pseudo inst: Add rpns (read processor nanoseconds) instruction. This instruction basically returns the number of nanoseconds that the CPU has been running. --- src/arch/alpha/isa/decoder.isa | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/arch') diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index 270940df2..115cf7fa7 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -806,6 +806,9 @@ decode OPCODE default Unknown::unknown() { 0x04: quiesceTime({{ R0 = PseudoInst::quiesceTime(xc->tcBase()); }}, IsNonSpeculative, IsUnverifiable); + 0x07: rpns({{ + R0 = PseudoInst::rpns(xc->tcBase()); + }}, IsNonSpeculative, IsUnverifiable); 0x10: deprecated_ivlb({{ warn_once("Obsolete M5 ivlb instruction encountered.\n"); }}); -- cgit v1.2.3 From 5711282f87afb609c79d657ed6aa8c9259b5b827 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 14 Nov 2008 04:55:30 -0800 Subject: Fix a bunch of bugs I introduced when I changed the flags stuff for packets. I did some of the flags and assertions wrong. Thanks to Brad Beckmann for pointing this out. I should have run the opt regressions instead of the fast. I also screwed up some of the logical functions in the Flags class. --- src/arch/alpha/isa/mem.isa | 2 +- src/arch/mips/isa/formats/util.isa | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/isa/mem.isa b/src/arch/alpha/isa/mem.isa index b4e10e849..cd5e117ec 100644 --- a/src/arch/alpha/isa/mem.isa +++ b/src/arch/alpha/isa/mem.isa @@ -678,7 +678,7 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, if mem_flags: mem_flags = [ 'Request::%s' % flag for flag in mem_flags ] - s = '\n\tmemAccessFlags.reset(' + string.join(mem_flags, '|') + ');' + s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' iop.constructor += s memacc_iop.constructor += s diff --git a/src/arch/mips/isa/formats/util.isa b/src/arch/mips/isa/formats/util.isa index 786a964d4..f729cbf63 100644 --- a/src/arch/mips/isa/formats/util.isa +++ b/src/arch/mips/isa/formats/util.isa @@ -62,7 +62,7 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, if mem_flags: mem_flags = [ 'Request::%s' % flag for flag in mem_flags ] - s = '\n\tmemAccessFlags.reset(' + string.join(mem_flags, '|') + ');' + s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' iop.constructor += s memacc_iop.constructor += s -- cgit v1.2.3 From 4514f565e3dfe1de41bbaec05f3f0074e5299bac Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 15 Nov 2008 09:30:10 -0800 Subject: syscalls: fix latent brk/obreak bug. Bogus calls to ChunkGenerator with negative size were triggering a new assertion that was added there. Also did a little renaming and cleanup in the process. --- src/arch/alpha/linux/process.cc | 2 +- src/arch/alpha/tru64/process.cc | 2 +- src/arch/mips/linux/process.cc | 4 ++-- src/arch/sparc/linux/syscalls.cc | 4 ++-- src/arch/sparc/solaris/process.cc | 2 +- src/arch/x86/linux/syscalls.cc | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc index 9527759ed..efcd6623e 100644 --- a/src/arch/alpha/linux/process.cc +++ b/src/arch/alpha/linux/process.cc @@ -136,7 +136,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", chmodFunc), /* 16 */ SyscallDesc("chown", chownFunc), - /* 17 */ SyscallDesc("brk", obreakFunc), + /* 17 */ SyscallDesc("brk", brkFunc), /* 18 */ SyscallDesc("osf_getfsstat", unimplementedFunc), /* 19 */ SyscallDesc("lseek", lseekFunc), /* 20 */ SyscallDesc("getxpid", getpidPseudoFunc), diff --git a/src/arch/alpha/tru64/process.cc b/src/arch/alpha/tru64/process.cc index 645cc6cf9..b84dfb286 100644 --- a/src/arch/alpha/tru64/process.cc +++ b/src/arch/alpha/tru64/process.cc @@ -215,7 +215,7 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { /* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", unimplementedFunc), /* 16 */ SyscallDesc("chown", unimplementedFunc), - /* 17 */ SyscallDesc("obreak", obreakFunc), + /* 17 */ SyscallDesc("obreak", brkFunc), /* 18 */ SyscallDesc("pre_F64_getfsstat", unimplementedFunc), /* 19 */ SyscallDesc("lseek", lseekFunc), /* 20 */ SyscallDesc("getpid", getpidPseudoFunc), diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc index 8a13d0f18..56413484b 100644 --- a/src/arch/mips/linux/process.cc +++ b/src/arch/mips/linux/process.cc @@ -138,7 +138,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", chmodFunc), /* 16 */ SyscallDesc("lchown", chownFunc), - /* 17 */ SyscallDesc("break", obreakFunc), + /* 17 */ SyscallDesc("break", brkFunc), /* 18 */ SyscallDesc("unused#18", unimplementedFunc), /* 19 */ SyscallDesc("lseek", lseekFunc), /* 20 */ SyscallDesc("getpid", getpidFunc), @@ -166,7 +166,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 42 */ SyscallDesc("pipe", pipePseudoFunc), /* 43 */ SyscallDesc("times", unimplementedFunc), /* 44 */ SyscallDesc("prof", unimplementedFunc), - /* 45 */ SyscallDesc("brk", obreakFunc), + /* 45 */ SyscallDesc("brk", brkFunc), /* 46 */ SyscallDesc("setgid", unimplementedFunc), /* 47 */ SyscallDesc("getgid", getgidFunc), /* 48 */ SyscallDesc("signal", ignoreFunc), diff --git a/src/arch/sparc/linux/syscalls.cc b/src/arch/sparc/linux/syscalls.cc index 2964b3c1a..2845f7bec 100644 --- a/src/arch/sparc/linux/syscalls.cc +++ b/src/arch/sparc/linux/syscalls.cc @@ -106,7 +106,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = { /* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", unimplementedFunc), /* 16 */ SyscallDesc("lchown", unimplementedFunc), //32 bit - /* 17 */ SyscallDesc("brk", obreakFunc), + /* 17 */ SyscallDesc("brk", brkFunc), /* 18 */ SyscallDesc("perfctr", unimplementedFunc), //32 bit /* 19 */ SyscallDesc("lseek", lseekFunc), //32 bit /* 20 */ SyscallDesc("getpid", getpidFunc), @@ -409,7 +409,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = { /* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", chmodFunc), /* 16 */ SyscallDesc("lchown", unimplementedFunc), - /* 17 */ SyscallDesc("brk", obreakFunc), + /* 17 */ SyscallDesc("brk", brkFunc), /* 18 */ SyscallDesc("perfctr", unimplementedFunc), /* 19 */ SyscallDesc("lseek", lseekFunc), /* 20 */ SyscallDesc("getpid", getpidFunc), diff --git a/src/arch/sparc/solaris/process.cc b/src/arch/sparc/solaris/process.cc index e0c3eaa4b..e4f6b23c8 100644 --- a/src/arch/sparc/solaris/process.cc +++ b/src/arch/sparc/solaris/process.cc @@ -80,7 +80,7 @@ SyscallDesc SparcSolarisProcess::syscallDescs[] = { /* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", chmodFunc), /* 16 */ SyscallDesc("chown", chownFunc), - /* 17 */ SyscallDesc("brk", obreakFunc), + /* 17 */ SyscallDesc("brk", brkFunc), /* 18 */ SyscallDesc("stat", unimplementedFunc), /* 19 */ SyscallDesc("lseek", lseekFunc), /* 20 */ SyscallDesc("getpid", getpidFunc), diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index ae2ac243b..754fb2eaf 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -135,7 +135,7 @@ SyscallDesc X86LinuxProcess::syscallDescs[] = { /* 9 */ SyscallDesc("mmap", mmapFunc), /* 10 */ SyscallDesc("mprotect", unimplementedFunc), /* 11 */ SyscallDesc("munmap", munmapFunc), - /* 12 */ SyscallDesc("brk", obreakFunc), + /* 12 */ SyscallDesc("brk", brkFunc), /* 13 */ SyscallDesc("rt_sigaction", unimplementedFunc), /* 14 */ SyscallDesc("rt_sigprocmask", unimplementedFunc), /* 15 */ SyscallDesc("rt_sigreturn", unimplementedFunc), -- cgit v1.2.3 From e2c7618e508c6e5c0cbbd091eabb336f3e259465 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Thu, 4 Dec 2008 18:03:35 -0500 Subject: This patch pulls out the auxiliary vector struct from individual ISA LiveProcesses to the base LiveProcess definition so anyone can use them. --- src/arch/sparc/process.hh | 20 -------------------- src/arch/x86/process.cc | 9 +++------ src/arch/x86/process.hh | 16 ---------------- 3 files changed, 3 insertions(+), 42 deletions(-) (limited to 'src/arch') diff --git a/src/arch/sparc/process.hh b/src/arch/sparc/process.hh index a37760139..95abb93d3 100644 --- a/src/arch/sparc/process.hh +++ b/src/arch/sparc/process.hh @@ -71,26 +71,6 @@ class SparcLiveProcess : public LiveProcess virtual void flushWindows(ThreadContext *tc) = 0; }; -template -struct M5_auxv_t -{ - IntType a_type; - union { - IntType a_val; - IntType a_ptr; - IntType a_fcn; - }; - - M5_auxv_t() - {} - - M5_auxv_t(IntType type, IntType val) - { - a_type = SparcISA::htog(type); - a_val = SparcISA::htog(val); - } -}; - class Sparc32LiveProcess : public SparcLiveProcess { protected: diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 52933b7f4..8d0cd5038 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -103,11 +103,6 @@ using namespace std; using namespace X86ISA; -M5_64_auxv_t::M5_64_auxv_t(int64_t type, int64_t val) -{ - a_type = X86ISA::htog(type); - a_val = X86ISA::htog(val); -} X86LiveProcess::X86LiveProcess(LiveProcessParams * params, ObjectFile *objFile) @@ -205,7 +200,9 @@ X86LiveProcess::startup() void X86LiveProcess::argsInit(int intSize, int pageSize) { - typedef M5_64_auxv_t auxv_t; + typedef M5_auxv_t auxv_t; + std::vector auxv; + Process::startup(); string filename; diff --git a/src/arch/x86/process.hh b/src/arch/x86/process.hh index 5def9e13d..d034d990e 100644 --- a/src/arch/x86/process.hh +++ b/src/arch/x86/process.hh @@ -64,26 +64,10 @@ namespace X86ISA { - struct M5_64_auxv_t - { - int64_t a_type; - union { - int64_t a_val; - int64_t a_ptr; - int64_t a_fcn; - }; - - M5_64_auxv_t() - {} - - M5_64_auxv_t(int64_t type, int64_t val); - }; class X86LiveProcess : public LiveProcess { protected: - std::vector auxv; - X86LiveProcess(LiveProcessParams * params, ObjectFile *objFile); void startup(); -- cgit v1.2.3 From f1430941cf17fc15a8b86eba41f9c856ad9347d8 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Fri, 5 Dec 2008 12:09:29 -0500 Subject: This brings M5 closer to modernity - the kernel being advertised is newer so it won't die on binaries compiled with newer glibc's, and enables use of TLS-toolchain built binaries for ALPHA_SE by putting auxiliary vectors on the stack. There are some comments in the code to help. Finally, stats changes for ALPHA are from slight perturbations to the initial stack frame, all minimal diffs. --- src/arch/alpha/linux/process.cc | 2 +- src/arch/alpha/process.cc | 118 ++++++++++++++++++++++++++++++++++++++++ src/arch/alpha/process.hh | 5 +- 3 files changed, 121 insertions(+), 4 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc index efcd6623e..6684051af 100644 --- a/src/arch/alpha/linux/process.cc +++ b/src/arch/alpha/linux/process.cc @@ -52,7 +52,7 @@ unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); - strcpy(name->release, "2.4.20"); + strcpy(name->release, "2.6.26"); strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003"); strcpy(name->machine, "alpha"); diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc index 28e8df308..3e5851e74 100644 --- a/src/arch/alpha/process.cc +++ b/src/arch/alpha/process.cc @@ -32,8 +32,11 @@ #include "arch/alpha/isa_traits.hh" #include "arch/alpha/process.hh" #include "base/loader/object_file.hh" +#include "base/loader/elf_object.hh" #include "base/misc.hh" #include "cpu/thread_context.hh" +#include "mem/page_table.hh" +#include "sim/process_impl.hh" #include "sim/system.hh" using namespace AlphaISA; @@ -57,6 +60,119 @@ AlphaLiveProcess::AlphaLiveProcess(LiveProcessParams *params, // Set pointer for next thread stack. Reserve 8M for main stack. next_thread_stack_base = stack_base - (8 * 1024 * 1024); +} + +void +AlphaLiveProcess::argsInit(int intSize, int pageSize) +{ + objFile->loadSections(initVirtMem); + + typedef M5_auxv_t auxv_t; + std::vector auxv; + + ElfObject * elfObject = dynamic_cast(objFile); + if(elfObject) + { + // modern glibc uses a bunch of auxiliary vectors to set up + // TLS as well as do a bunch of other stuff + // these vectors go on the bottom of the stack, below argc/argv/envp + // pointers but above actual arg strings + // I don't have all the ones glibc looks at here, but so far it doesn't + // seem to be a problem. + // check out _dl_aux_init() in glibc/elf/dl-support.c for details + // --Lisa + auxv.push_back(auxv_t(M5_AT_PAGESZ, AlphaISA::VMPageSize)); + auxv.push_back(auxv_t(M5_AT_CLKTCK, 100)); + auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable())); + DPRINTF(Loader, "auxv at PHDR %08p\n", elfObject->programHeaderTable()); + auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount())); + auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint())); + auxv.push_back(auxv_t(M5_AT_UID, uid())); + auxv.push_back(auxv_t(M5_AT_EUID, euid())); + auxv.push_back(auxv_t(M5_AT_GID, gid())); + auxv.push_back(auxv_t(M5_AT_EGID, egid())); + + } + + // Calculate how much space we need for arg & env & auxv arrays. + int argv_array_size = intSize * (argv.size() + 1); + int envp_array_size = intSize * (envp.size() + 1); + int auxv_array_size = intSize * 2 * (auxv.size() + 1); + + int arg_data_size = 0; + for (int i = 0; i < argv.size(); ++i) { + arg_data_size += argv[i].size() + 1; + } + int env_data_size = 0; + for (int i = 0; i < envp.size(); ++i) { + env_data_size += envp[i].size() + 1; + } + + int space_needed = + argv_array_size + + envp_array_size + + auxv_array_size + + arg_data_size + + env_data_size; + + if (space_needed < 32*1024) + space_needed = 32*1024; + + // set bottom of stack + stack_min = stack_base - space_needed; + // align it + stack_min = roundDown(stack_min, pageSize); + stack_size = stack_base - stack_min; + // map memory + pTable->allocate(stack_min, roundUp(stack_size, pageSize)); + + // map out initial stack contents + Addr argv_array_base = stack_min + intSize; // room for argc + Addr envp_array_base = argv_array_base + argv_array_size; + Addr auxv_array_base = envp_array_base + envp_array_size; + Addr arg_data_base = auxv_array_base + auxv_array_size; + Addr env_data_base = arg_data_base + arg_data_size; + + // write contents to stack + uint64_t argc = argv.size(); + if (intSize == 8) + argc = htog((uint64_t)argc); + else if (intSize == 4) + argc = htog((uint32_t)argc); + else + panic("Unknown int size"); + + initVirtMem->writeBlob(stack_min, (uint8_t*)&argc, intSize); + + copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem); + copyStringArray(envp, envp_array_base, env_data_base, initVirtMem); + + //Copy the aux stuff + for(int x = 0; x < auxv.size(); x++) + { + initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize, + (uint8_t*)&(auxv[x].a_type), intSize); + initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize, + (uint8_t*)&(auxv[x].a_val), intSize); + } + + assert(NumArgumentRegs >= 2); + + ThreadContext *tc = system->getThreadContext(contextIds[0]); + + tc->setIntReg(ArgumentReg[0], argc); + tc->setIntReg(ArgumentReg[1], argv_array_base); + tc->setIntReg(StackPointerReg, stack_min); + + Addr prog_entry = objFile->entryPoint(); + tc->setPC(prog_entry); + tc->setNextPC(prog_entry + sizeof(MachInst)); + +#if THE_ISA != ALPHA_ISA //e.g. MIPS or Sparc + tc->setNextNPC(prog_entry + (2 * sizeof(MachInst))); +#endif + + } void @@ -65,6 +181,8 @@ AlphaLiveProcess::startup() if (checkpointRestored) return; + Process::startup(); + argsInit(MachineBytes, VMPageSize); ThreadContext *tc = system->getThreadContext(contextIds[0]); diff --git a/src/arch/alpha/process.hh b/src/arch/alpha/process.hh index 0aeeb25db..65c4624ae 100644 --- a/src/arch/alpha/process.hh +++ b/src/arch/alpha/process.hh @@ -34,15 +34,14 @@ #include "sim/process.hh" -class ObjectFile; -class System; - class AlphaLiveProcess : public LiveProcess { protected: AlphaLiveProcess(LiveProcessParams *params, ObjectFile *objFile); void startup(); + + void argsInit(int intSize, int pageSize); }; #endif // __ARCH_ALPHA_PROCESS_HH__ -- cgit v1.2.3 From e141cb7441e79b3596c795faf9f47424f26c65e9 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 6 Dec 2008 14:18:18 -0800 Subject: flags: Change naming of functions to be clearer --- src/arch/alpha/faults.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc index e89cf5c64..e93e16711 100644 --- a/src/arch/alpha/faults.cc +++ b/src/arch/alpha/faults.cc @@ -144,7 +144,7 @@ DtbFault::invoke(ThreadContext *tc) // read, like the EV5). The EV6 approach is cleaner and seems to // work with EV5 PAL code, but not the other way around. if (!tc->misspeculating() && - reqFlags.none(Request::VPTE|Request::NO_FAULT)) { + reqFlags.noneSet(Request::VPTE|Request::NO_FAULT)) { // set VA register with faulting address tc->setMiscRegNoEffect(IPR_VA, vaddr); -- cgit v1.2.3 From e4790bcbe29b82dc81d4f34b78bb6ee2f718806a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 6 Dec 2008 14:48:59 -0800 Subject: X86: Add add_entry back in. --- src/arch/x86/bios/IntelMP.py | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/bios/IntelMP.py b/src/arch/x86/bios/IntelMP.py index 70e7963fa..758932180 100644 --- a/src/arch/x86/bios/IntelMP.py +++ b/src/arch/x86/bios/IntelMP.py @@ -86,6 +86,15 @@ class X86IntelMPConfigTable(SimObject): ext_entries = VectorParam.X86IntelMPExtConfigEntry([], 'extended configuration table entries') + def add_entry(self, entry): + if isinstance(entry, X86IntelMPBaseConfigEntry): + self.base_entries.append(entry) + elif isinstance(entry, X86IntelMPExtConfigEntry): + self.base_entries.append(entry) + else: + panic("Don't know what type of Intel MP entry %s is." \ + % entry.__class__.__name__) + class X86IntelMPBaseConfigEntry(SimObject): type = 'X86IntelMPBaseConfigEntry' cxx_class = 'X86ISA::IntelMP::BaseConfigEntry' -- cgit v1.2.3 From 993b7be4bb3dae5b15cd4c23a4c0e4c3dc7ed734 Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Sun, 7 Dec 2008 15:07:42 -0500 Subject: imported patch aux-fix.patch --- src/arch/alpha/process.cc | 2 +- src/arch/sparc/process.cc | 2 +- src/arch/x86/process.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc index 3e5851e74..004be1ec0 100644 --- a/src/arch/alpha/process.cc +++ b/src/arch/alpha/process.cc @@ -67,7 +67,7 @@ AlphaLiveProcess::argsInit(int intSize, int pageSize) { objFile->loadSections(initVirtMem); - typedef M5_auxv_t auxv_t; + typedef AuxVector auxv_t; std::vector auxv; ElfObject * elfObject = dynamic_cast(objFile); diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 987e0465e..91baea40c 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -189,7 +189,7 @@ SparcLiveProcess::argsInit(int pageSize) { int intSize = sizeof(IntType); - typedef M5_auxv_t auxv_t; + typedef AuxVector auxv_t; std::vector auxv; diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 8d0cd5038..2013190eb 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -200,7 +200,7 @@ X86LiveProcess::startup() void X86LiveProcess::argsInit(int intSize, int pageSize) { - typedef M5_auxv_t auxv_t; + typedef AuxVector auxv_t; std::vector auxv; Process::startup(); -- cgit v1.2.3 From 02cd18f536544d4b5fa19681b4c9dbd5b2cb87ff Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 16 Dec 2008 23:06:37 -0800 Subject: SPARC: Truncate syscall args and return values appropriately. --- src/arch/sparc/syscallreturn.hh | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/sparc/syscallreturn.hh b/src/arch/sparc/syscallreturn.hh index cf13fc3e8..d4e6c7c50 100644 --- a/src/arch/sparc/syscallreturn.hh +++ b/src/arch/sparc/syscallreturn.hh @@ -50,13 +50,23 @@ namespace SparcISA tc->setIntReg(NumIntArchRegs + 2, tc->readIntReg(NumIntArchRegs + 2) & 0xEE); //tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) & 0xEE); - tc->setIntReg(ReturnValueReg, return_value.value()); + IntReg val = return_value.value(); + if (bits(tc->readMiscRegNoEffect( + SparcISA::MISCREG_PSTATE), 3, 3)) { + val = bits(val, 31, 0); + } + tc->setIntReg(ReturnValueReg, val); } else { // got an error, set XCC.C tc->setIntReg(NumIntArchRegs + 2, tc->readIntReg(NumIntArchRegs + 2) | 0x11); //tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) | 0x11); - tc->setIntReg(ReturnValueReg, -return_value.value()); + IntReg val = -return_value.value(); + if (bits(tc->readMiscRegNoEffect( + SparcISA::MISCREG_PSTATE), 3, 3)) { + val = bits(val, 31, 0); + } + tc->setIntReg(ReturnValueReg, val); } } }; -- cgit v1.2.3 From 1704ba2273d9623095ddcd269055aedb8e818e03 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Wed, 17 Dec 2008 09:51:18 -0800 Subject: Make Alpha pseudo-insts available from SE mode. --- src/arch/alpha/isa/decoder.isa | 21 ++++++++++++++++----- src/arch/alpha/isa/main.isa | 2 -- 2 files changed, 16 insertions(+), 7 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index 115cf7fa7..f057f00cc 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -783,14 +783,19 @@ decode OPCODE default Unknown::unknown() { } } - format BasicOperate { - 0x1e: decode PALMODE { - 0: OpcdecFault::hw_rei(); - 1:hw_rei({{ xc->hwrei(); }}, IsSerializing, IsSerializeBefore); + 0x1e: decode PALMODE { + 0: OpcdecFault::hw_rei(); + format BasicOperate { + 1: hw_rei({{ xc->hwrei(); }}, IsSerializing, IsSerializeBefore); } + } + +#endif + format BasicOperate { // M5 special opcodes use the reserved 0x01 opcode space 0x01: decode M5FUNC { +#if FULL_SYSTEM 0x00: arm({{ PseudoInst::arm(xc->tcBase()); }}, IsNonSpeculative); @@ -806,6 +811,7 @@ decode OPCODE default Unknown::unknown() { 0x04: quiesceTime({{ R0 = PseudoInst::quiesceTime(xc->tcBase()); }}, IsNonSpeculative, IsUnverifiable); +#endif 0x07: rpns({{ R0 = PseudoInst::rpns(xc->tcBase()); }}, IsNonSpeculative, IsUnverifiable); @@ -822,12 +828,14 @@ decode OPCODE default Unknown::unknown() { 0x21: m5exit({{ PseudoInst::m5exit(xc->tcBase(), R16); }}, No_OpClass, IsNonSpeculative); +#if FULL_SYSTEM 0x31: loadsymbol({{ PseudoInst::loadsymbol(xc->tcBase()); }}, No_OpClass, IsNonSpeculative); 0x30: initparam({{ Ra = xc->tcBase()->getCpuPtr()->system->init_param; }}); +#endif 0x40: resetstats({{ PseudoInst::resetstats(xc->tcBase(), R16, R17); }}, IsNonSpeculative); @@ -840,18 +848,22 @@ decode OPCODE default Unknown::unknown() { 0x43: m5checkpoint({{ PseudoInst::m5checkpoint(xc->tcBase(), R16, R17); }}, IsNonSpeculative); +#if FULL_SYSTEM 0x50: m5readfile({{ R0 = PseudoInst::readfile(xc->tcBase(), R16, R17, R18); }}, IsNonSpeculative); +#endif 0x51: m5break({{ PseudoInst::debugbreak(xc->tcBase()); }}, IsNonSpeculative); 0x52: m5switchcpu({{ PseudoInst::switchcpu(xc->tcBase()); }}, IsNonSpeculative); +#if FULL_SYSTEM 0x53: m5addsymbol({{ PseudoInst::addsymbol(xc->tcBase(), R16, R17); }}, IsNonSpeculative); +#endif 0x54: m5panic({{ panic("M5 panic instruction called at pc=%#x.", xc->readPC()); }}, IsNonSpeculative); @@ -872,5 +884,4 @@ decode OPCODE default Unknown::unknown() { }}, IsNonSpeculative); } } -#endif } diff --git a/src/arch/alpha/isa/main.isa b/src/arch/alpha/isa/main.isa index 5231712c8..f34bd4b33 100644 --- a/src/arch/alpha/isa/main.isa +++ b/src/arch/alpha/isa/main.isa @@ -68,9 +68,7 @@ using namespace AlphaISA; output exec {{ #include -#if FULL_SYSTEM #include "sim/pseudo_inst.hh" -#endif #include "arch/alpha/ipr.hh" #include "base/fenv.hh" #include "config/ss_compatible_fp.hh" -- cgit v1.2.3 From 7b7a72158ab194864e7985e68fc5161b563b44a8 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 6 Jan 2009 22:40:41 -0800 Subject: X86: Change indentation on microop disassembly. --- src/arch/x86/insts/static_inst.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/insts/static_inst.cc b/src/arch/x86/insts/static_inst.cc index 0c1508d5a..15fc4bee6 100644 --- a/src/arch/x86/insts/static_inst.cc +++ b/src/arch/x86/insts/static_inst.cc @@ -63,13 +63,13 @@ namespace X86ISA void X86StaticInst::printMnemonic(std::ostream &os, const char * mnemonic) const { - ccprintf(os, "\t%s ", mnemonic); + ccprintf(os, " %s ", mnemonic); } void X86StaticInst::printMnemonic(std::ostream &os, const char * instMnemonic, const char * mnemonic) const { - ccprintf(os, "\t%s : %s ", instMnemonic, mnemonic); + ccprintf(os, " %s : %s ", instMnemonic, mnemonic); } void X86StaticInst::printSegment(std::ostream &os, int segment) const -- cgit v1.2.3 From 9e24d8c599a3090f3ce59a608ff887ac434aa1ca Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 6 Jan 2009 22:44:59 -0800 Subject: X86: Move the macroop class out of the isa description into C++. --- src/arch/x86/insts/macroop.hh | 119 ++++++++++++++++++++++++++++++++++++++++++ src/arch/x86/isa/includes.isa | 1 + src/arch/x86/isa/macroop.isa | 50 ++---------------- 3 files changed, 124 insertions(+), 46 deletions(-) create mode 100644 src/arch/x86/insts/macroop.hh (limited to 'src/arch') diff --git a/src/arch/x86/insts/macroop.hh b/src/arch/x86/insts/macroop.hh new file mode 100644 index 000000000..d89a693ba --- /dev/null +++ b/src/arch/x86/insts/macroop.hh @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2007 The Hewlett-Packard Development Company + * All rights reserved. + * + * Redistribution and use of this software in source and binary forms, + * with or without modification, are permitted provided that the + * following conditions are met: + * + * The software must be used only for Non-Commercial Use which means any + * use which is NOT directed to receiving any direct monetary + * compensation for, or commercial advantage from such use. Illustrative + * examples of non-commercial use are academic research, personal study, + * teaching, education and corporate research & development. + * Illustrative examples of commercial use are distributing products for + * commercial advantage and providing services using the software for + * commercial advantage. + * + * If you wish to use this software or functionality therein that may be + * covered by patents for commercial use, please contact: + * Director of Intellectual Property Licensing + * Office of Strategy and Technology + * Hewlett-Packard Company + * 1501 Page Mill Road + * Palo Alto, California 94304 + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. Redistributions + * in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. Neither the name of + * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. No right of + * sublicense is granted herewith. Derivatives of the software and + * output created using the software may be prepared, but only for + * Non-Commercial Uses. Derivatives of the software may be shared with + * others provided: (i) the others agree to abide by the list of + * conditions herein which includes the Non-Commercial Use restrictions; + * and (ii) such Derivatives of the software include the above copyright + * notice to acknowledge the contribution from this software where + * applicable, this list of conditions and the disclaimer below. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#ifndef __ARCH_X86_INSTS_MACROOP_HH__ +#define __ARCH_X86_INSTS_MACROOP_HH__ + +#include "arch/x86/emulenv.hh" +#include "arch/x86/types.hh" +#include "arch/x86/insts/static_inst.hh" + +namespace X86ISA +{ +// Base class for combinationally generated macroops +class MacroopBase : public StaticInst +{ + protected: + const uint32_t numMicroops; + X86ISA::EmulEnv emulEnv; + + //Constructor. + MacroopBase(const char *mnem, ExtMachInst _machInst, + uint32_t _numMicroops, X86ISA::EmulEnv _emulEnv) + : StaticInst(mnem, _machInst, No_OpClass), + numMicroops(_numMicroops), emulEnv(_emulEnv) + { + assert(numMicroops); + microops = new StaticInstPtr[numMicroops]; + flags[IsMacroop] = true; + } + + ~MacroopBase() + { + delete [] microops; + } + + StaticInstPtr * microops; + + StaticInstPtr fetchMicroop(MicroPC microPC) + { + assert(microPC < numMicroops); + return microops[microPC]; + } + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + return mnemonic; + } + + public: + ExtMachInst + getExtMachInst() + { + return machInst; + } + + X86ISA::EmulEnv + getEmulEnv() + { + return emulEnv; + } +}; +} + +#endif //__ARCH_X86_INSTS_MACROOP_HH__ diff --git a/src/arch/x86/isa/includes.isa b/src/arch/x86/isa/includes.isa index e523b7e32..cddc4247c 100644 --- a/src/arch/x86/isa/includes.isa +++ b/src/arch/x86/isa/includes.isa @@ -97,6 +97,7 @@ output header {{ #include #include "arch/x86/emulenv.hh" +#include "arch/x86/insts/macroop.hh" #include "arch/x86/insts/microfpop.hh" #include "arch/x86/insts/microldstop.hh" #include "arch/x86/insts/microregop.hh" diff --git a/src/arch/x86/isa/macroop.isa b/src/arch/x86/isa/macroop.isa index 7d94dd95c..c5134f336 100644 --- a/src/arch/x86/isa/macroop.isa +++ b/src/arch/x86/isa/macroop.isa @@ -72,56 +72,14 @@ def template MacroExecPanic {{ output header {{ // Base class for combinationally generated macroops - class Macroop : public StaticInst + class Macroop : public X86ISA::MacroopBase { - protected: - const uint32_t numMicroops; - X86ISA::EmulEnv emulEnv; - - //Constructor. + public: Macroop(const char *mnem, ExtMachInst _machInst, uint32_t _numMicroops, X86ISA::EmulEnv _emulEnv) - : StaticInst(mnem, _machInst, No_OpClass), - numMicroops(_numMicroops), emulEnv(_emulEnv) - { - assert(numMicroops); - microops = new StaticInstPtr[numMicroops]; - flags[IsMacroop] = true; - } - - ~Macroop() - { - delete [] microops; - } - - StaticInstPtr * microops; - - StaticInstPtr fetchMicroop(MicroPC microPC) - { - assert(microPC < numMicroops); - return microops[microPC]; - } - - std::string generateDisassembly(Addr pc, - const SymbolTable *symtab) const - { - return mnemonic; - } - - public: + : MacroopBase(mnem, _machInst, _numMicroops, _emulEnv) + {} %(MacroExecPanic)s - - ExtMachInst - getExtMachInst() - { - return machInst; - } - - X86ISA::EmulEnv - getEmulEnv() - { - return emulEnv; - } }; }}; -- cgit v1.2.3 From 8cab1805f9854d74b4a73c5c3b316aa7ad2d2177 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 6 Jan 2009 22:46:28 -0800 Subject: X86: Move the function that prints memory args into the inst base class. --- src/arch/x86/insts/microldstop.cc | 29 ++--------------------------- src/arch/x86/insts/static_inst.cc | 38 ++++++++++++++++++++++++++++++++++++++ src/arch/x86/insts/static_inst.hh | 3 +++ 3 files changed, 43 insertions(+), 27 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/insts/microldstop.cc b/src/arch/x86/insts/microldstop.cc index 9638a2ae3..7cc6a330f 100644 --- a/src/arch/x86/insts/microldstop.cc +++ b/src/arch/x86/insts/microldstop.cc @@ -64,7 +64,6 @@ namespace X86ISA const SymbolTable *symtab) const { std::stringstream response; - bool someAddr = false; printMnemonic(response, instMnem, mnemonic); if(flags[IsLoad]) @@ -72,32 +71,8 @@ namespace X86ISA else printSrcReg(response, 2, dataSize); response << ", "; - printSegment(response, segment); - response << ":["; - if(scale != 0 && _srcRegIdx[0] != ZeroReg) - { - if(scale != 1) - ccprintf(response, "%d*", scale); - printSrcReg(response, 0, addressSize); - someAddr = true; - } - if(_srcRegIdx[1] != ZeroReg) - { - if(someAddr) - response << " + "; - printSrcReg(response, 1, addressSize); - someAddr = true; - } - if(disp != 0) - { - if(someAddr) - response << " + "; - ccprintf(response, "%#x", disp); - someAddr = true; - } - if(!someAddr) - response << "0"; - response << "]"; + printMem(response, segment, scale, index, base, disp, + addressSize, false); return response.str(); } } diff --git a/src/arch/x86/insts/static_inst.cc b/src/arch/x86/insts/static_inst.cc index 15fc4bee6..f4ed44603 100644 --- a/src/arch/x86/insts/static_inst.cc +++ b/src/arch/x86/insts/static_inst.cc @@ -240,6 +240,44 @@ namespace X86ISA } } + void X86StaticInst::printMem(std::ostream &os, uint8_t segment, + uint8_t scale, RegIndex index, RegIndex base, + uint64_t disp, uint8_t addressSize, bool rip) const + { + bool someAddr = false; + printSegment(os, segment); + os << ":["; + if (rip) { + os << "rip"; + someAddr = true; + } else { + if (scale != 0 && index != ZeroReg) + { + if(scale != 1) + ccprintf(os, "%d*", scale); + printReg(os, index, addressSize); + someAddr = true; + } + if (base != ZeroReg) + { + if(someAddr) + os << " + "; + printReg(os, base, addressSize); + someAddr = true; + } + } + if (disp != 0) + { + if(someAddr) + os << " + "; + ccprintf(os, "%#x", disp); + someAddr = true; + } + if (!someAddr) + os << "0"; + os << "]"; + } + std::string X86StaticInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const { diff --git a/src/arch/x86/insts/static_inst.hh b/src/arch/x86/insts/static_inst.hh index e5c333e75..8480f2713 100644 --- a/src/arch/x86/insts/static_inst.hh +++ b/src/arch/x86/insts/static_inst.hh @@ -89,6 +89,9 @@ namespace X86ISA void printReg(std::ostream &os, int reg, int size) const; void printSrcReg(std::ostream &os, int reg, int size) const; void printDestReg(std::ostream &os, int reg, int size) const; + void printMem(std::ostream &os, uint8_t segment, + uint8_t scale, RegIndex index, RegIndex base, + uint64_t disp, uint8_t addressSize, bool rip) const; inline uint64_t merge(uint64_t into, uint64_t val, int size) const { -- cgit v1.2.3 From 115b1a7ed350b9f1171b3f1b39c4c0875d1c0a5f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 6 Jan 2009 22:55:27 -0800 Subject: X86: Autogenerate macroop generateDisassemble function. --- src/arch/x86/insts/macroop.hh | 18 +++++---- src/arch/x86/isa/macroop.isa | 71 ++++++++++++++++++++++++++++++------ src/arch/x86/isa/microops/base.isa | 2 +- src/arch/x86/isa/microops/debug.isa | 2 +- src/arch/x86/isa/microops/fpop.isa | 2 +- src/arch/x86/isa/microops/ldstop.isa | 2 +- src/arch/x86/isa/microops/limmop.isa | 2 +- src/arch/x86/isa/microops/regop.isa | 2 +- src/arch/x86/isa/microops/seqop.isa | 2 +- src/arch/x86/isa/microops/specop.isa | 4 +- src/arch/x86/isa/specialize.isa | 46 +++++++++++++++++++++-- 11 files changed, 121 insertions(+), 32 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/insts/macroop.hh b/src/arch/x86/insts/macroop.hh index d89a693ba..d6925a1a5 100644 --- a/src/arch/x86/insts/macroop.hh +++ b/src/arch/x86/insts/macroop.hh @@ -65,17 +65,19 @@ namespace X86ISA { // Base class for combinationally generated macroops -class MacroopBase : public StaticInst +class MacroopBase : public X86StaticInst { protected: + const char *macrocodeBlock; + const uint32_t numMicroops; - X86ISA::EmulEnv emulEnv; + X86ISA::EmulEnv env; //Constructor. MacroopBase(const char *mnem, ExtMachInst _machInst, - uint32_t _numMicroops, X86ISA::EmulEnv _emulEnv) - : StaticInst(mnem, _machInst, No_OpClass), - numMicroops(_numMicroops), emulEnv(_emulEnv) + uint32_t _numMicroops, X86ISA::EmulEnv _env) : + X86StaticInst(mnem, _machInst, No_OpClass), + numMicroops(_numMicroops), env(_env) { assert(numMicroops); microops = new StaticInstPtr[numMicroops]; @@ -95,8 +97,8 @@ class MacroopBase : public StaticInst return microops[microPC]; } - std::string generateDisassembly(Addr pc, - const SymbolTable *symtab) const + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const { return mnemonic; } @@ -111,7 +113,7 @@ class MacroopBase : public StaticInst X86ISA::EmulEnv getEmulEnv() { - return emulEnv; + return env; } }; } diff --git a/src/arch/x86/isa/macroop.isa b/src/arch/x86/isa/macroop.isa index c5134f336..8eaf5f786 100644 --- a/src/arch/x86/isa/macroop.isa +++ b/src/arch/x86/isa/macroop.isa @@ -76,8 +76,8 @@ output header {{ { public: Macroop(const char *mnem, ExtMachInst _machInst, - uint32_t _numMicroops, X86ISA::EmulEnv _emulEnv) - : MacroopBase(mnem, _machInst, _numMicroops, _emulEnv) + uint32_t _numMicroops, X86ISA::EmulEnv _env) + : MacroopBase(mnem, _machInst, _numMicroops, _env) {} %(MacroExecPanic)s }; @@ -102,22 +102,42 @@ def template MacroDeclare {{ %(declareLabels)s public: // Constructor. - %(class_name)s(ExtMachInst machInst, X86ISA::EmulEnv env); + %(class_name)s(ExtMachInst machInst, X86ISA::EmulEnv _env); + + std::string + generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; }; }}; +def template MacroDisassembly {{ + std::string + X86Macroop::%(class_name)s::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream out; + out << mnemonic << "\t"; + + int regSize = %(regSize)s; + %(disassembly)s + // Shut up gcc. + regSize = regSize; + return out.str(); + } +}}; + // Basic instruction class constructor template. def template MacroConstructor {{ inline X86Macroop::%(class_name)s::%(class_name)s( - ExtMachInst machInst, EmulEnv env) - : %(base_class)s("%(mnemonic)s", machInst, %(num_microops)s, env) + ExtMachInst machInst, EmulEnv _env) + : %(base_class)s("%(mnemonic)s", machInst, %(num_microops)s, _env) { %(adjust_env)s; %(adjust_imm)s; %(adjust_disp)s; %(do_modrm)s; %(constructor)s; + const char *macrocodeBlock = "%(class_name)s"; //alloc_microops is the code that sets up the microops //array in the parent class. %(alloc_microops)s; @@ -158,7 +178,12 @@ let {{ adjustedDisp = adjustedDisp; ''' def getAllocator(self, env): - return "new X86Macroop::%s(machInst, %s)" % (self.name, env.getAllocator()) + return "new X86Macroop::%s(machInst, %s)" % \ + (self.name, env.getAllocator()) + def getMnemonic(self): + mnemonic = self.name.lower() + mnemonic = re.match(r'[^_]*', mnemonic).group(0) + return mnemonic def getDeclaration(self): #FIXME This first parameter should be the mnemonic. I need to #write some code which pulls that out @@ -166,12 +191,12 @@ let {{ for (label, microop) in self.labels.items(): declareLabels += "const static uint64_t label_%s = %d;\n" \ % (label, microop.micropc) - iop = InstObjParams(self.name, self.name, "Macroop", + iop = InstObjParams(self.getMnemonic(), self.name, "Macroop", {"code" : "", "declareLabels" : declareLabels }) return MacroDeclare.subst(iop); - def getDefinition(self): + def getDefinition(self, env): #FIXME This first parameter should be the mnemonic. I need to #write some code which pulls that out numMicroops = len(self.microops) @@ -184,14 +209,28 @@ let {{ (micropc, op.getAllocator(True, not isLast, micropc == 0, isLast)) micropc += 1 - iop = InstObjParams(self.name, self.name, "Macroop", + if env.useStackSize: + useStackSize = "true" + else: + useStackSize = "false" + if env.memoryInst: + memoryInst = "true" + else: + memoryInst = "false" + regSize = '''(%s || (env.base == INTREG_RSP && %s) ? + env.stackSize : + env.dataSize)''' % (useStackSize, memoryInst) + iop = InstObjParams(self.getMnemonic(), self.name, "Macroop", {"code" : "", "num_microops" : numMicroops, "alloc_microops" : allocMicroops, "adjust_env" : self.adjust_env, "adjust_imm" : self.adjust_imm, "adjust_disp" : self.adjust_disp, + "disassembly" : env.disassembly, + "regSize" : regSize, "do_modrm" : self.doModRM}) - return MacroConstructor.subst(iop); + return MacroConstructor.subst(iop) + \ + MacroDisassembly.subst(iop); }}; let {{ @@ -207,6 +246,16 @@ let {{ self.dataSize = "OPSIZE" self.stackSize = "STACKSIZE" self.doModRM = False + self.disassembly = "" + self.firstArgument = True + self.useStackSize = False + self.memoryInst = False + + def addToDisassembly(self, code): + if not self.firstArgument: + self.disassembly += "out << \", \";\n" + self.firstArgument = False + self.disassembly += code def getAllocator(self): if self.size == 'b': @@ -264,7 +313,7 @@ let {{ if env.doModRM: macroop.doModRM = doModRMString blocks.header_output = macroop.getDeclaration() - blocks.decoder_output = macroop.getDefinition() + blocks.decoder_output = macroop.getDefinition(env) macroop.declared = True blocks.decode_block = "return %s;\n" % macroop.getAllocator(env) return blocks diff --git a/src/arch/x86/isa/microops/base.isa b/src/arch/x86/isa/microops/base.isa index 2b73cf563..f1007bf71 100644 --- a/src/arch/x86/isa/microops/base.isa +++ b/src/arch/x86/isa/microops/base.isa @@ -76,7 +76,7 @@ let {{ StaticInstPtr ''' + generatorNameTemplate + '''(StaticInstPtr curMacroop) { - static const char * mnemonic = romMnemonic; + static const char *macrocodeBlock = romMnemonic; static const ExtMachInst dummyExtMachInst; static const EmulEnv dummyEmulEnv(0, 0, 1, 1, 1); diff --git a/src/arch/x86/isa/microops/debug.isa b/src/arch/x86/isa/microops/debug.isa index 895e97199..38fee59bb 100644 --- a/src/arch/x86/isa/microops/debug.isa +++ b/src/arch/x86/isa/microops/debug.isa @@ -183,7 +183,7 @@ let {{ self.cond = "0" def getAllocator(self, *microFlags): - allocator = '''new %(class_name)s(machInst, mnemonic + allocator = '''new %(class_name)s(machInst, macrocodeBlock %(flags)s, "%(message)s", %(cc)s)''' % { "class_name" : self.className, "flags" : self.microFlagsText(microFlags), diff --git a/src/arch/x86/isa/microops/fpop.isa b/src/arch/x86/isa/microops/fpop.isa index 2919aa277..d4acfdbf4 100644 --- a/src/arch/x86/isa/microops/fpop.isa +++ b/src/arch/x86/isa/microops/fpop.isa @@ -245,7 +245,7 @@ let {{ self.className += "Top" def getAllocator(self, *microFlags): - return '''new %(class_name)s(machInst, mnemonic + return '''new %(class_name)s(machInst, macrocodeBlock %(flags)s, %(src1)s, %(src2)s, %(dest)s, %(dataSize)s, %(spm)d)''' % { "class_name" : self.className, diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index 30a7c8801..8a0af14be 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -362,7 +362,7 @@ let {{ self.addressSize = addressSize def getAllocator(self, *microFlags): - allocator = '''new %(class_name)s(machInst, mnemonic + allocator = '''new %(class_name)s(machInst, macrocodeBlock %(flags)s, %(scale)s, %(index)s, %(base)s, %(disp)s, %(segment)s, %(data)s, %(dataSize)s, %(addressSize)s)''' % { diff --git a/src/arch/x86/isa/microops/limmop.isa b/src/arch/x86/isa/microops/limmop.isa index 6686444fd..4e75ab8b0 100644 --- a/src/arch/x86/isa/microops/limmop.isa +++ b/src/arch/x86/isa/microops/limmop.isa @@ -154,7 +154,7 @@ let {{ self.dataSize = dataSize def getAllocator(self, *microFlags): - allocator = '''new %(class_name)s(machInst, mnemonic + allocator = '''new %(class_name)s(machInst, macrocodeBlock %(flags)s, %(dest)s, %(imm)s, %(dataSize)s)''' % { "class_name" : self.className, "mnemonic" : self.mnemonic, diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 944d5e9ec..492452a51 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -438,7 +438,7 @@ let {{ className = self.className if self.mnemonic == self.base_mnemonic + 'i': className += "Imm" - allocator = '''new %(class_name)s(machInst, mnemonic + allocator = '''new %(class_name)s(machInst, macrocodeBlock %(flags)s, %(src1)s, %(op2)s, %(dest)s, %(dataSize)s, %(ext)s)''' % { "class_name" : className, diff --git a/src/arch/x86/isa/microops/seqop.isa b/src/arch/x86/isa/microops/seqop.isa index f03094f66..332519b87 100644 --- a/src/arch/x86/isa/microops/seqop.isa +++ b/src/arch/x86/isa/microops/seqop.isa @@ -181,7 +181,7 @@ let {{ self.cond = "0" def getAllocator(self, *microFlags): - allocator = '''new %(class_name)s(machInst, mnemonic + allocator = '''new %(class_name)s(machInst, macrocodeBlock %(flags)s, %(target)s, %(cc)s)''' % { "class_name" : self.className, "flags" : self.microFlagsText(microFlags), diff --git a/src/arch/x86/isa/microops/specop.isa b/src/arch/x86/isa/microops/specop.isa index ad14b54a3..c6e172ef1 100644 --- a/src/arch/x86/isa/microops/specop.isa +++ b/src/arch/x86/isa/microops/specop.isa @@ -230,7 +230,7 @@ let {{ self.cond = "0" def getAllocator(self, *microFlags): - allocator = '''new %(class_name)s(machInst, mnemonic + allocator = '''new %(class_name)s(machInst, macrocodeBlock %(flags)s, %(fault)s, %(cc)s)''' % { "class_name" : self.className, "flags" : self.microFlagsText(microFlags), @@ -257,7 +257,7 @@ let {{ pass def getAllocator(self, *microFlags): - return "new MicroHalt(machInst, mnemonic %s)" % \ + return "new MicroHalt(machInst, macrocodeBlock %s)" % \ self.microFlagsText(microFlags) microopClasses["halt"] = Halt diff --git a/src/arch/x86/isa/specialize.isa b/src/arch/x86/isa/specialize.isa index abf734307..b74363470 100644 --- a/src/arch/x86/isa/specialize.isa +++ b/src/arch/x86/isa/specialize.isa @@ -86,8 +86,17 @@ let {{ let {{ def doRipRelativeDecode(Name, opTypes, env): # print "RIPing %s with opTypes %s" % (Name, opTypes) - normBlocks = specializeInst(Name + "_M", copy.copy(opTypes), copy.copy(env)) - ripBlocks = specializeInst(Name + "_P", copy.copy(opTypes), copy.copy(env)) + env.memoryInst = True + normEnv = copy.copy(env) + normEnv.addToDisassembly( + '''printMem(out, env.seg, env.scale, env.index, env.base, + machInst.displacement, env.addressSize, false);''') + normBlocks = specializeInst(Name + "_M", copy.copy(opTypes), normEnv) + ripEnv = copy.copy(env) + ripEnv.addToDisassembly( + '''printMem(out, env.seg, 1, 0, 0, + machInst.displacement, env.addressSize, true);''') + ripBlocks = specializeInst(Name + "_P", copy.copy(opTypes), ripEnv) blocks = OutputBlocks() blocks.append(normBlocks) @@ -138,12 +147,17 @@ let {{ #Figure out what to do with fixed register operands #This is the index to use, so we should stick it some place. if opType.reg in ("A", "B", "C", "D"): - env.addReg("INTREG_R%sX" % opType.reg) + regString = "INTREG_R%sX" % opType.reg else: - env.addReg("INTREG_R%s" % opType.reg) + regString = "INTREG_R%s" % opType.reg + env.addReg(regString) + env.addToDisassembly( + "printReg(out, %s, regSize);\n" % regString) Name += "_R" elif opType.tag == "B": # This refers to registers whose index is encoded as part of the opcode + env.addToDisassembly( + "printReg(out, %s, regSize);\n" % InstRegIndex) Name += "_R" env.addReg(InstRegIndex) elif opType.tag == "M": @@ -156,24 +170,34 @@ let {{ elif opType.tag == "C": # A control register indexed by the "reg" field env.addReg(ModRMRegIndex) + env.addToDisassembly( + "ccprintf(out, \"CR%%d\", %s);\n" % ModRMRegIndex) Name += "_C" elif opType.tag == "D": # A debug register indexed by the "reg" field env.addReg(ModRMRegIndex) + env.addToDisassembly( + "ccprintf(out, \"DR%%d\", %s);\n" % ModRMRegIndex) Name += "_D" elif opType.tag == "S": # A segment selector register indexed by the "reg" field env.addReg(ModRMRegIndex) + env.addToDisassembly( + "printSegment(out, %s);\n" % ModRMRegIndex) Name += "_S" elif opType.tag in ("G", "P", "T", "V"): # Use the "reg" field of the ModRM byte to select the register env.addReg(ModRMRegIndex) + env.addToDisassembly( + "printReg(out, %s, regSize);\n" % ModRMRegIndex) Name += "_R" elif opType.tag in ("E", "Q", "W"): # This might refer to memory or to a register. We need to # divide it up farther. regEnv = copy.copy(env) regEnv.addReg(ModRMRMIndex) + regEnv.addToDisassembly( + "printReg(out, %s, regSize);\n" % ModRMRMIndex) # This refers to memory. The macroop constructor should set up # modrm addressing. memEnv = copy.copy(env) @@ -183,6 +207,8 @@ let {{ (doRipRelativeDecode, Name, copy.copy(opTypes), memEnv)) elif opType.tag in ("I", "J"): # Immediates + env.addToDisassembly( + "ccprintf(out, \"%#x\", machInst.immediate);\n") Name += "_I" elif opType.tag == "O": # Immediate containing a memory offset @@ -190,10 +216,22 @@ let {{ elif opType.tag in ("PR", "R", "VR"): # Non register modrm settings should cause an error env.addReg(ModRMRMIndex) + env.addToDisassembly( + "printReg(out, %s, regSize);\n" % ModRMRMIndex) Name += "_R" elif opType.tag in ("X", "Y"): # This type of memory addressing is for string instructions. # They'll use the right index and segment internally. + if opType.tag == "X": + env.addToDisassembly( + '''printMem(out, env.seg, + 1, X86ISA::ZeroReg, X86ISA::INTREG_RSI, 0, + env.addressSize, false);''') + else: + env.addToDisassembly( + '''printMem(out, SEGMENT_REG_ES, + 1, X86ISA::ZeroReg, X86ISA::INTREG_RDI, 0, + env.addressSize, false);''') Name += "_M" else: raise Exception, "Unrecognized tag %s." % opType.tag -- cgit v1.2.3 From b23633ad1b3210d54386a9bab8c453f2bb4b7874 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 6 Jan 2009 23:55:46 -0800 Subject: X86: Hook in the M5 pseudo insts. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 92 ++++++++++++++++++++++++++- src/arch/x86/isa/formats/basic.isa | 8 +++ src/arch/x86/isa/includes.isa | 1 + src/arch/x86/isa/operands.isa | 4 ++ src/arch/x86/predecoder_tables.cc | 2 +- 5 files changed, 104 insertions(+), 3 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index b8013165e..4ebe03d84 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -163,8 +163,96 @@ } 0x02: lar_Gv_Ew(); 0x03: lsl_Gv_Ew(); - //sandpile.org doesn't seem to know what this is... ? - 0x04: loadall_or_reset_or_hang(); + // sandpile.org doesn't seem to know what this is...? We'll + // use it for pseudo instructions. We've got 16 bits of space + // to play with so there can be quite a few pseudo + // instructions. + //0x04: loadall_or_reset_or_hang(); + 0x4: decode IMMEDIATE { + format BasicOperate { +#if FULL_SYSTEM + 0x00: m5arm({{ + PseudoInst::arm(xc->tcBase()); + }}, IsNonSpeculative); + 0x01: m5quiesce({{ + PseudoInst::quiesce(xc->tcBase()); + }}, IsNonSpeculative); + 0x02: m5quiesceNs({{ + PseudoInst::quiesceNs(xc->tcBase(), Rdi); + }}, IsNonSpeculative); + 0x03: m5quiesceCycle({{ + PseudoInst::quiesceCycles(xc->tcBase(), Rdi); + }}, IsNonSpeculative); + 0x04: m5quiesceTime({{ + Rax = PseudoInst::quiesceTime(xc->tcBase()); + }}, IsNonSpeculative); +#endif + 0x07: m5rpns({{ + Rax = PseudoInst::rpns(xc->tcBase()); + }}, IsNonSpeculative); + 0x21: m5exit({{ + PseudoInst::m5exit(xc->tcBase(), Rdi); + }}, IsNonSpeculative); +#if FULL_SYSTEM + 0x30: m5initparam({{ + Rax = xc->tcBase()->getCpuPtr()-> + system->init_param; + }}, IsNonSpeculative); + 0x31: m5loadsymbol({{ + PseudoInst::loadsymbol(xc->tcBase()); + }}, IsNonSpeculative); +#endif + 0x40: m5resetstats({{ + PseudoInst::resetstats(xc->tcBase(), Rdi, Rsi); + }}, IsNonSpeculative); + 0x41: m5dumpstats({{ + PseudoInst::dumpstats(xc->tcBase(), Rdi, Rsi); + }}, IsNonSpeculative); + 0x42: m5dumpresetstats({{ + PseudoInst::dumpresetstats(xc->tcBase(), Rdi, Rsi); + }}, IsNonSpeculative); + 0x43: m5checkpoint({{ + PseudoInst::m5checkpoint(xc->tcBase(), Rdi, Rsi); + }}, IsNonSpeculative); +#if FULL_SYSTEM + 0x50: m5readfile({{ + Rax = PseudoInst::readfile( + xc->tcBase(), Rdi, Rsi, Rdx); + }}, IsNonSpeculative); +#endif + 0x51: m5debugbreak({{ + PseudoInst::debugbreak(xc->tcBase()); + }}, IsNonSpeculative); + 0x52: m5switchcpu({{ + PseudoInst::switchcpu(xc->tcBase()); + }}, IsNonSpeculative); +#if FULL_SYSTEM + 0x53: m5addsymbol({{ + PseudoInst::addsymbol(xc->tcBase(), Rdi, Rsi); + }}, IsNonSpeculative); +#endif + 0x54: m5panic({{ + panic("M5 panic instruction called at pc=%#x.\n", + xc->readPC()); + }}, IsNonSpeculative); + 0x55: m5reserved1({{ + warn("M5 reserved opcode 1 ignored.\n"); + }}, IsNonSpeculative); + 0x56: m5reserved2({{ + warn("M5 reserved opcode 2 ignored.\n"); + }}, IsNonSpeculative); + 0x57: m5reserved3({{ + warn("M5 reserved opcode 3 ignored.\n"); + }}, IsNonSpeculative); + 0x58: m5reserved4({{ + warn("M5 reserved opcode 4 ignored.\n"); + }}, IsNonSpeculative); + 0x59: m5reserved5({{ + warn("M5 reserved opcode 5 ignored.\n"); + }}, IsNonSpeculative); + default: Inst::UD2(); + } + } #if FULL_SYSTEM 0x05: syscall(); #else diff --git a/src/arch/x86/isa/formats/basic.isa b/src/arch/x86/isa/formats/basic.isa index 7aea7085f..b96bae238 100644 --- a/src/arch/x86/isa/formats/basic.isa +++ b/src/arch/x86/isa/formats/basic.isa @@ -147,3 +147,11 @@ def template BasicDecode {{ def template BasicDecodeWithMnemonic {{ return new %(class_name)s("%(mnemonic)s", machInst); }}; + +def format BasicOperate(code, *flags) {{ + iop = InstObjParams(name, Name, 'X86ISA::X86StaticInst', code, flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; diff --git a/src/arch/x86/isa/includes.isa b/src/arch/x86/isa/includes.isa index cddc4247c..909f2f389 100644 --- a/src/arch/x86/isa/includes.isa +++ b/src/arch/x86/isa/includes.isa @@ -156,6 +156,7 @@ output exec {{ #include "sim/sim_exit.hh" #include "mem/packet.hh" #include "mem/packet_access.hh" +#include "sim/pseudo_inst.hh" using namespace X86ISA; using namespace std; diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index 343b37d41..a409d1f0f 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -113,6 +113,10 @@ def operands {{ 'Rbx': ('IntReg', 'uqw', '(INTREG_RBX)', 'IsInteger', 13), 'Rcx': ('IntReg', 'uqw', '(INTREG_RCX)', 'IsInteger', 14), 'Rdx': ('IntReg', 'uqw', '(INTREG_RDX)', 'IsInteger', 15), + 'Rsp': ('IntReg', 'uqw', '(INTREG_RSP)', 'IsInteger', 16), + 'Rbp': ('IntReg', 'uqw', '(INTREG_RBP)', 'IsInteger', 17), + 'Rsi': ('IntReg', 'uqw', '(INTREG_RSI)', 'IsInteger', 18), + 'Rdi': ('IntReg', 'uqw', '(INTREG_RDI)', 'IsInteger', 19), 'FpSrcReg1': ('FloatReg', 'df', 'src1', 'IsFloating', 20), 'FpSrcReg2': ('FloatReg', 'df', 'src2', 'IsFloating', 21), 'FpDestReg': ('FloatReg', 'df', 'dest', 'IsFloating', 22), diff --git a/src/arch/x86/predecoder_tables.cc b/src/arch/x86/predecoder_tables.cc index bcd5face6..5f2b5c421 100644 --- a/src/arch/x86/predecoder_tables.cc +++ b/src/arch/x86/predecoder_tables.cc @@ -201,7 +201,7 @@ namespace X86ISA //For two byte instructions { //LSB // MSB 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F -/* 0 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , BY , +/* 0 */ 0 , 0 , 0 , 0 , WO, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , BY , /* 0 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* 2 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /* 3 */ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , -- cgit v1.2.3 From 8153790d0004439f8e9d473da97699644234117b Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Tue, 13 Jan 2009 14:17:50 -0800 Subject: SCons: centralize the Dir() workaround for newer versions of scons. Scons bug id: 2006 M5 Bug id: 308 --- src/arch/mips/SConscript | 3 --- src/arch/sparc/SConscript | 4 ---- src/arch/x86/SConscript | 14 -------------- 3 files changed, 21 deletions(-) (limited to 'src/arch') diff --git a/src/arch/mips/SConscript b/src/arch/mips/SConscript index 0368e68bc..0b470def6 100644 --- a/src/arch/mips/SConscript +++ b/src/arch/mips/SConscript @@ -33,9 +33,6 @@ Import('*') if env['TARGET_ISA'] == 'mips': -# Workaround for bug in SCons version > 0.97d20071212 -# Scons bug id: 2006 M5 Bug id: 308 - Dir('isa/formats') Source('faults.cc') Source('regfile/int_regfile.cc') Source('regfile/float_regfile.cc') diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript index 126587835..6a4c08a8e 100644 --- a/src/arch/sparc/SConscript +++ b/src/arch/sparc/SConscript @@ -32,10 +32,6 @@ Import('*') if env['TARGET_ISA'] == 'sparc': -# Workaround for bug in SCons version > 0.97d20071212 -# Scons bug id: 2006 M5 Bug id: 308 - Dir('isa/formats') - Dir('isa/formats/mem') Source('asi.cc') Source('faults.cc') Source('floatregfile.cc') diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript index c2081156d..37719e75d 100644 --- a/src/arch/x86/SConscript +++ b/src/arch/x86/SConscript @@ -357,17 +357,3 @@ if env['TARGET_ISA'] == 'x86': # Only non-header files need to be compiled. if not f.path.endswith('.hh'): Source(f) - - # Workaround for bug in SCons version > 0.97d20071212 - # Scons bug id: 2006 M5 Bug id: 308 - from os.path import dirname, join as joinpath - - Dir('isa') - Dir('isa/microops') - Dir('isa/decoder') - Dir('isa/formats') - Dir('isa/insts') - isa_dirs = set(map(lambda x:dirname(x), python_files)) - for d in isa_dirs: - Dir(joinpath('isa/insts', d)) - -- cgit v1.2.3 From c9d3113015c69766f65851addf41172b9bc046b2 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 19 Jan 2009 09:59:14 -0800 Subject: tracing: Add help strings for some of the trace flags --- src/arch/sparc/SConscript | 2 +- src/arch/x86/SConscript | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/arch') diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript index 6a4c08a8e..148277358 100644 --- a/src/arch/sparc/SConscript +++ b/src/arch/sparc/SConscript @@ -44,7 +44,7 @@ if env['TARGET_ISA'] == 'sparc': Source('utility.cc') SimObject('SparcTLB.py') - TraceFlag('Sparc') + TraceFlag('Sparc', "Generic SPARC ISA stuff") if env['FULL_SYSTEM']: SimObject('SparcSystem.py') diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript index 37719e75d..a57e388ea 100644 --- a/src/arch/x86/SConscript +++ b/src/arch/x86/SConscript @@ -106,11 +106,11 @@ if env['TARGET_ISA'] == 'x86': Source('utility.cc') SimObject('X86TLB.py') - TraceFlag('Predecoder') - TraceFlag('X86') + TraceFlag('Predecoder', "Predecoder debug output") + TraceFlag('X86', "Generic X86 ISA debugging") if env['FULL_SYSTEM']: - TraceFlag('LocalApic') + TraceFlag('LocalApic', "Local APIC debugging") SimObject('X86LocalApic.py') SimObject('X86System.py') -- cgit v1.2.3 From 64ed39f61b89675237e145ed4a81b49f353921ed Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 24 Jan 2009 07:27:22 -0800 Subject: pseudo inst: Add new wake cpu instruction for sending a message to wake a cpu. It's instantaneous and so it's somewhat bogus, but it's a first step. --- src/arch/alpha/isa/decoder.isa | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/arch') diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index f057f00cc..67bc5c7a2 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -815,6 +815,9 @@ decode OPCODE default Unknown::unknown() { 0x07: rpns({{ R0 = PseudoInst::rpns(xc->tcBase()); }}, IsNonSpeculative, IsUnverifiable); + 0x09: wakeCPU({{ + PseudoInst::wakeCPU(xc->tcBase(), R16); + }}, IsNonSpeculative, IsUnverifiable); 0x10: deprecated_ivlb({{ warn_once("Obsolete M5 ivlb instruction encountered.\n"); }}); -- cgit v1.2.3 From d9794784bac54483660e438980d592b6ffe5c311 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 25 Jan 2009 20:29:03 -0800 Subject: CPU: Add a setCPU function to the interrupt objects. --- src/arch/alpha/interrupts.hh | 9 ++++++++- src/arch/sparc/interrupts.hh | 12 ++++++++++-- src/arch/x86/interrupts.hh | 9 +++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/interrupts.hh b/src/arch/alpha/interrupts.hh index 89db134ff..f8e0ad4ef 100644 --- a/src/arch/alpha/interrupts.hh +++ b/src/arch/alpha/interrupts.hh @@ -48,6 +48,7 @@ class Interrupts : public SimObject bool newInfoSet; int newIpl; int newSummary; + BaseCPU * cpu; protected: uint64_t interrupts[NumInterruptLevels]; @@ -62,13 +63,19 @@ class Interrupts : public SimObject return dynamic_cast(_params); } - Interrupts(Params * p) : SimObject(p) + Interrupts(Params * p) : SimObject(p), cpu(NULL) { memset(interrupts, 0, sizeof(interrupts)); intstatus = 0; newInfoSet = false; } + void + setCPU(BaseCPU * _cpu) + { + cpu = _cpu; + } + void post(int int_num, int index) { diff --git a/src/arch/sparc/interrupts.hh b/src/arch/sparc/interrupts.hh index 66b3792b5..ec930e2b0 100644 --- a/src/arch/sparc/interrupts.hh +++ b/src/arch/sparc/interrupts.hh @@ -43,12 +43,20 @@ namespace SparcISA class Interrupts : public SimObject { - private: + BaseCPU * cpu; + uint64_t interrupts[NumInterruptTypes]; uint64_t intStatus; public: + + void + setCPU(BaseCPU * _cpu) + { + cpu = _cpu; + } + typedef SparcInterruptsParams Params; const Params * @@ -57,7 +65,7 @@ class Interrupts : public SimObject return dynamic_cast(_params); } - Interrupts(Params * p) : SimObject(p) + Interrupts(Params * p) : SimObject(p), cpu(NULL) { clearAll(); } diff --git a/src/arch/x86/interrupts.hh b/src/arch/x86/interrupts.hh index 8c7316217..c5e3bde0d 100644 --- a/src/arch/x86/interrupts.hh +++ b/src/arch/x86/interrupts.hh @@ -69,6 +69,7 @@ #include "sim/eventq.hh" class ThreadContext; +class BaseCPU; namespace X86ISA { @@ -182,12 +183,20 @@ class Interrupts : public BasicPioDevice, IntDev void requestInterrupt(uint8_t vector, uint8_t deliveryMode, bool level); + BaseCPU *cpu; + public: /* * Params stuff. */ typedef X86LocalApicParams Params; + void + setCPU(BaseCPU * newCPU) + { + cpu = newCPU; + } + void setClock(Tick newClock) { -- cgit v1.2.3 From 389fbfdab19332ad191e9abed1c12a673fb7eda9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 25 Jan 2009 20:30:51 -0800 Subject: X86: Make the interrupt object wake up the CPU when something becomes pending. --- src/arch/x86/interrupts.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'src/arch') diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index a16ea5360..4f7753703 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -281,6 +281,7 @@ X86ISA::Interrupts::requestInterrupt(uint8_t vector, initVector = vector; } } + cpu->wakeup(); } Tick -- cgit v1.2.3 From 0449fb2b7a51f911d9814b79250047fa8f083829 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 25 Jan 2009 20:31:17 -0800 Subject: X86: Fix a bug in the iret microcode. --- .../general_purpose/control_transfer/interrupts_and_exceptions.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py index 57bc13698..1f14eb95c 100644 --- a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py +++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py @@ -75,6 +75,8 @@ def macroop IRET_PROT { ld t2, ss, [1, t0, rsp], "1 * env.stackSize", dataSize=ssz ld t3, ss, [1, t0, rsp], "2 * env.stackSize", dataSize=ssz + # Read the handy m5 register for use later + rdm5reg t4 ### @@ -89,7 +91,6 @@ def macroop IRET_PROT { br label("protToVirtFallThrough"), flags=(nCECF,) #CPL=0 - rdm5reg t4 andi t0, t4, 0x30, flags=(EZF,) br label("protToVirtFallThrough"), flags=(nCEZF,) -- cgit v1.2.3 From 3c5988b86c9fcb06927a8e12095e278b55593911 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 25 Jan 2009 20:32:43 -0800 Subject: X86: Implement the bswap instruction. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 6 +++++- .../data_conversion/endian_conversion.py | 20 +++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index 4ebe03d84..064f5ce86 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -915,7 +915,11 @@ default: Inst::UD2(); } } - 0x19: bswap_B(); + 0x19: decode OPSIZE { + 4: Inst::BSWAP_D(Bd); + 8: Inst::BSWAP_Q(Bq); + default: Inst::UD2(); + } 0x1A: decode LEGACY_DECODEVAL { // no prefix 0x0: decode OPCODE_OP_BOTTOM3 { diff --git a/src/arch/x86/isa/insts/general_purpose/data_conversion/endian_conversion.py b/src/arch/x86/isa/insts/general_purpose/data_conversion/endian_conversion.py index b375ac27e..ac2343462 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_conversion/endian_conversion.py +++ b/src/arch/x86/isa/insts/general_purpose/data_conversion/endian_conversion.py @@ -53,7 +53,25 @@ # # Authors: Gabe Black -microcode = "" +microcode = ''' +def macroop BSWAP_D_R +{ + roli reg, reg, 8, dataSize=2 + roli reg, reg, 16, dataSize=4 + roli reg, reg, 8, dataSize=2 +}; + +def macroop BSWAP_Q_R +{ + roli reg, reg, 8, dataSize=2 + roli reg, reg, 16, dataSize=4 + roli reg, reg, 8, dataSize=2 + roli reg, reg, 32, dataSize=8 + roli reg, reg, 8, dataSize=2 + roli reg, reg, 16, dataSize=4 + roli reg, reg, 8, dataSize=2 +}; +''' #let {{ # class BSWAP(Inst): # "GenFault ${new UnimpInstFault}" -- cgit v1.2.3 From 52defeb4e76e7f426c91eb0d0e5e2222d2ab387e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 25 Jan 2009 20:33:27 -0800 Subject: X86: Implement the xadd instruction. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 4 ++-- .../x86/isa/insts/general_purpose/semaphores.py | 24 ++++++++++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index 064f5ce86..3cdfa48bb 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -870,8 +870,8 @@ 0x7: Inst::MOVSX_W(Gv,Ev); } 0x18: decode OPCODE_OP_BOTTOM3 { - 0x0: xadd_Eb_Gb(); - 0x1: xadd_Ev_Gv(); + 0x0: Inst::XADD(Eb,Gb); + 0x1: Inst::XADD(Ev,Gv); //0x7: group9(); 0x7: decode MODRM_REG { 0x1: cmpxchg_Mq(); diff --git a/src/arch/x86/isa/insts/general_purpose/semaphores.py b/src/arch/x86/isa/insts/general_purpose/semaphores.py index da16477fc..f23241863 100644 --- a/src/arch/x86/isa/insts/general_purpose/semaphores.py +++ b/src/arch/x86/isa/insts/general_purpose/semaphores.py @@ -78,10 +78,30 @@ def macroop CMPXCHG_P_R { st t1, seg, riprel, disp mov rax, rax, t1, flags=(nCZF,) }; + +def macroop XADD_M_R { + ldst t1, seg, sib, disp + add t2, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) + st t2, seg, sib, disp + mov reg, reg, t1 +}; + +def macroop XADD_P_R { + rdip t7 + ldst t1, seg, riprel, disp + add t2, t1, reg, flags=(OF,SF,ZF,AF,PF,CF) + st t2, seg, riprel, disp + mov reg, reg, t1 +}; + +def macroop XADD_R_R { + add t2, regm, reg, flags=(OF,SF,ZF,AF,PF,CF) + mov regm, regm, reg + mov reg, reg, t2 +}; + ''' #let {{ -# class XADD(Inst): -# "GenFault ${new UnimpInstFault}" # class XCHG(Inst): # "GenFault ${new UnimpInstFault}" #}}; -- cgit v1.2.3 From e7293dd24eb15ce568ffbb2f6aa8ae60f88472b1 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Fri, 30 Jan 2009 20:04:17 -0500 Subject: Errors: Use the correct panic/warn/fatal/info message in some places. --- src/arch/sparc/tlb.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index 875ae1411..9e5230674 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -1129,7 +1129,7 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) break; case ASI_SPARC_ERROR_EN_REG: case ASI_SPARC_ERROR_STATUS_REG: - warn("Ignoring write to SPARC ERROR regsiter\n"); + inform("Ignoring write to SPARC ERROR regsiter\n"); break; case ASI_HYP_SCRATCHPAD: case ASI_SCRATCHPAD: -- cgit v1.2.3 From 953e4bba59262ed4ee7268e5f49b992d7b0c02d6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 1 Feb 2009 16:59:34 -0800 Subject: X86: Set/correct some default values for x86 parameters. --- src/arch/x86/bios/ACPI.py | 2 +- src/arch/x86/bios/IntelMP.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/bios/ACPI.py b/src/arch/x86/bios/ACPI.py index 20eb66be0..6f7cae946 100644 --- a/src/arch/x86/bios/ACPI.py +++ b/src/arch/x86/bios/ACPI.py @@ -94,6 +94,6 @@ class X86ACPIRSDP(SimObject): # here. revision = Param.UInt8(2, 'revision of ACPI being used, zero indexed') - rsdt = Param.X86ACPIRSDT('root system description table') + rsdt = Param.X86ACPIRSDT(NULL, 'root system description table') xsdt = Param.X86ACPIXSDT(X86ACPIXSDT(), 'extended system description table') diff --git a/src/arch/x86/bios/IntelMP.py b/src/arch/x86/bios/IntelMP.py index 758932180..1b9e819b3 100644 --- a/src/arch/x86/bios/IntelMP.py +++ b/src/arch/x86/bios/IntelMP.py @@ -115,9 +115,9 @@ class X86IntelMPProcessor(X86IntelMPBaseConfigEntry): enable = Param.Bool(True, 'if this processor is usable') bootstrap = Param.Bool(False, 'if this is the bootstrap processor') - stepping = Param.UInt8(0) - model = Param.UInt8(0) - family = Param.UInt8(0) + stepping = Param.UInt8(0, 'Processor stepping') + model = Param.UInt8(0, 'Processor model') + family = Param.UInt8(0, 'Processor family') feature_flags = Param.UInt32(0, 'flags returned by the CPUID instruction') -- cgit v1.2.3 From 483c3e96b7e30d3bd788f32c5b421133e71ec476 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 1 Feb 2009 00:08:16 -0800 Subject: X86: Calculate flags based on the actual result. --- src/arch/x86/insts/microregop.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/insts/microregop.cc b/src/arch/x86/insts/microregop.cc index 080926627..2ea975746 100644 --- a/src/arch/x86/insts/microregop.cc +++ b/src/arch/x86/insts/microregop.cc @@ -67,6 +67,9 @@ namespace X86ISA bool subtract) const { DPRINTF(X86, "flagMask = %#x\n", flagMask); + if (_destRegIdx[0] & (1 << 6)) { + _dest >>= 8; + } uint64_t flags = oldFlags & ~flagMask; if(flagMask & (ECFBit | CFBit)) { -- cgit v1.2.3 From 06cdbe5ea7138d0f340448438d64e98c72936e1b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 1 Feb 2009 00:11:49 -0800 Subject: X86: Compute PCI config addresses correctly. --- src/arch/x86/tlb.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 6f1c1a03c..1009386d7 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -547,7 +547,8 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) tc->readMiscRegNoEffect(MISCREG_PCI_CONFIG_ADDRESS); if (bits(configAddress, 31, 31)) { req->setPaddr(PhysAddrPrefixPciConfig | - bits(configAddress, 30, 0)); + mbits(configAddress, 30, 2) | + (IOPort & mask(2))); } } else { req->setPaddr(PhysAddrPrefixIO | IOPort); -- cgit v1.2.3 From f3b8371dfcad39c609e4bf5ecf50c17e57fca805 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 1 Feb 2009 00:15:38 -0800 Subject: X86: Add extended Intel MP entries correctly. --- src/arch/x86/bios/IntelMP.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/bios/IntelMP.py b/src/arch/x86/bios/IntelMP.py index 1b9e819b3..04e79b6ac 100644 --- a/src/arch/x86/bios/IntelMP.py +++ b/src/arch/x86/bios/IntelMP.py @@ -90,7 +90,7 @@ class X86IntelMPConfigTable(SimObject): if isinstance(entry, X86IntelMPBaseConfigEntry): self.base_entries.append(entry) elif isinstance(entry, X86IntelMPExtConfigEntry): - self.base_entries.append(entry) + self.ext_entries.append(entry) else: panic("Don't know what type of Intel MP entry %s is." \ % entry.__class__.__name__) -- cgit v1.2.3 From d432bd13b2f4796a4a9a97831c521ab66aadc414 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 1 Feb 2009 00:18:13 -0800 Subject: X86: Fix some incorrect register widths. --- src/arch/x86/isa/operands.isa | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index a409d1f0f..d46741f00 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -159,7 +159,7 @@ def operands {{ 'CSAttr': ('ControlReg', 'udw', 'MISCREG_CS_ATTR', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 208), 'MiscRegDest': ('ControlReg', 'uqw', 'dest', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 209), 'MiscRegSrc1': ('ControlReg', 'uqw', 'src1', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 210), - 'TscOp': ('ControlReg', 'udw', 'MISCREG_TSC', (None, None, ['IsSerializeAfter', 'IsSerializing', 'IsNonSpeculative']), 211), - 'M5Reg': ('ControlReg', 'udw', 'MISCREG_M5_REG', (None, None, None), 212), + 'TscOp': ('ControlReg', 'uqw', 'MISCREG_TSC', (None, None, ['IsSerializeAfter', 'IsSerializing', 'IsNonSpeculative']), 211), + 'M5Reg': ('ControlReg', 'uqw', 'MISCREG_M5_REG', (None, None, None), 212), 'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 300) }}; -- cgit v1.2.3 From ca6e0d75c8343e707f5632e12af8e797160d3e6c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 1 Feb 2009 00:28:28 -0800 Subject: X86: Fix the microcode for the LODS instruction. --- src/arch/x86/isa/insts/general_purpose/string/load_string.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/string/load_string.py b/src/arch/x86/isa/insts/general_purpose/string/load_string.py index 8d144dc4d..14198701a 100644 --- a/src/arch/x86/isa/insts/general_purpose/string/load_string.py +++ b/src/arch/x86/isa/insts/general_purpose/string/load_string.py @@ -61,9 +61,9 @@ def macroop LODS_M { subi t4, t0, dsz, dataSize=asz mov t3, t3, t4, flags=(nCEZF,), dataSize=asz - ld rax, seg, [1, t0, rdi] + ld rax, seg, [1, t0, rsi] - add rdi, rdi, t3, dataSize=asz + add rsi, rsi, t3, dataSize=asz }; def macroop LODS_E_M { @@ -76,10 +76,10 @@ def macroop LODS_E_M { mov t3, t3, t4, flags=(nCEZF,), dataSize=asz topOfLoop: - ld rax, seg, [1, t0, rdi] + ld rax, seg, [1, t0, rsi] subi rcx, rcx, 1, flags=(EZF,), dataSize=asz - add rdi, rdi, t3, dataSize=asz + add rsi, rsi, t3, dataSize=asz br label("topOfLoop"), flags=(nCEZF,) end: fault "NoFault" -- cgit v1.2.3 From 6b60a2970637129a39f04724ff082b2b0ffc1eb1 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 1 Feb 2009 00:30:11 -0800 Subject: X86: Fix the time keeping of the Local APIC timer. --- src/arch/x86/interrupts.cc | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index 4f7753703..29157b3f5 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -344,10 +344,19 @@ X86ISA::Interrupts::readReg(ApicRegIndex reg) break; case APIC_CURRENT_COUNT: { - assert(clock); - uint32_t val = regs[reg] - curTick / clock; - val /= (16 * divideFromConf(regs[APIC_DIVIDE_CONFIGURATION])); - return val; + if (apicTimerEvent.scheduled()) { + assert(clock); + // Compute how many m5 ticks happen per count. + uint64_t ticksPerCount = clock * + divideFromConf(regs[APIC_DIVIDE_CONFIGURATION]); + // Compute how many m5 ticks are left. + uint64_t val = apicTimerEvent.when() - curTick; + // Turn that into a count. + val = (val + ticksPerCount - 1) / ticksPerCount; + return val; + } else { + return 0; + } } default: break; @@ -441,19 +450,17 @@ X86ISA::Interrupts::setReg(ApicRegIndex reg, uint32_t val) { assert(clock); newVal = bits(val, 31, 0); - uint32_t newCount = newVal * - (divideFromConf(regs[APIC_DIVIDE_CONFIGURATION]) * 16); - regs[APIC_CURRENT_COUNT] = newCount + curTick / clock; - // Find out how long a "tick" of the timer should take. - Tick timerTick = 16 * clock; + // Compute how many timer ticks we're being programmed for. + uint64_t newCount = newVal * + (divideFromConf(regs[APIC_DIVIDE_CONFIGURATION])); // Schedule on the edge of the next tick plus the new count. - Tick offset = curTick % timerTick; + Tick offset = curTick % clock; if (offset) { reschedule(apicTimerEvent, - curTick + (newCount + 1) * timerTick - offset, true); + curTick + (newCount + 1) * clock - offset, true); } else { reschedule(apicTimerEvent, - curTick + newCount * timerTick, true); + curTick + newCount * clock, true); } } break; -- cgit v1.2.3 From 03a00735c2d15e393f328cb05c6e560a85923225 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 1 Feb 2009 17:03:11 -0800 Subject: X86: Keep track of the vector for all exceptions/faults. --- src/arch/x86/faults.hh | 67 +++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 33 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/faults.hh b/src/arch/x86/faults.hh index 3bcacffe2..dc86d2cec 100644 --- a/src/arch/x86/faults.hh +++ b/src/arch/x86/faults.hh @@ -69,11 +69,13 @@ namespace X86ISA protected: const char * faultName; const char * mnem; + uint8_t vector; uint64_t errorCode; X86FaultBase(const char * _faultName, const char * _mnem, - uint64_t _errorCode = 0) : - faultName(_faultName), mnem(_mnem), errorCode(_errorCode) + const uint8_t _vector, uint64_t _errorCode = 0) : + faultName(_faultName), mnem(_mnem), + vector(_vector), errorCode(_errorCode) { } @@ -105,8 +107,8 @@ namespace X86ISA { protected: X86Fault(const char * name, const char * mnem, - uint64_t _errorCode = 0) : - X86FaultBase(name, mnem, _errorCode) + const uint8_t vector, uint64_t _errorCode = 0) : + X86FaultBase(name, mnem, vector, _errorCode) {} }; @@ -116,8 +118,8 @@ namespace X86ISA { protected: X86Trap(const char * name, const char * mnem, - uint64_t _errorCode = 0) : - X86FaultBase(name, mnem, _errorCode) + const uint8_t vector, uint64_t _errorCode = 0) : + X86FaultBase(name, mnem, vector, _errorCode) {} #if FULL_SYSTEM @@ -130,8 +132,8 @@ namespace X86ISA { protected: X86Abort(const char * name, const char * mnem, - uint64_t _errorCode = 0) : - X86FaultBase(name, mnem, _errorCode) + const uint8_t vector, uint64_t _errorCode = 0) : + X86FaultBase(name, mnem, vector, _errorCode) {} #if FULL_SYSTEM @@ -143,10 +145,9 @@ namespace X86ISA class X86Interrupt : public X86FaultBase { protected: - uint8_t vector; - X86Interrupt(const char * name, const char * mnem, uint8_t _vector, - uint64_t _errorCode = 0) : - X86FaultBase(name, mnem, _errorCode), vector(_vector) + X86Interrupt(const char * name, const char * mnem, + const uint8_t _vector, uint64_t _errorCode = 0) : + X86FaultBase(name, mnem, _vector, _errorCode) {} #if FULL_SYSTEM @@ -208,7 +209,7 @@ namespace X86ISA { public: DivideByZero() : - X86Fault("Divide-by-Zero-Error", "#DE") + X86Fault("Divide-by-Zero-Error", "#DE", 0) {} }; @@ -216,7 +217,7 @@ namespace X86ISA { public: DebugException() : - X86FaultBase("Debug", "#DB") + X86FaultBase("Debug", "#DB", 1) {} }; @@ -224,7 +225,7 @@ namespace X86ISA { public: NonMaskableInterrupt(uint8_t _vector) : - X86Interrupt("Non Maskable Interrupt", "#NMI", _vector) + X86Interrupt("Non Maskable Interrupt", "#NMI", 2, _vector) {} }; @@ -232,7 +233,7 @@ namespace X86ISA { public: Breakpoint() : - X86Trap("Breakpoint", "#BP") + X86Trap("Breakpoint", "#BP", 3) {} }; @@ -240,7 +241,7 @@ namespace X86ISA { public: OverflowTrap() : - X86Trap("Overflow", "#OF") + X86Trap("Overflow", "#OF", 4) {} }; @@ -248,7 +249,7 @@ namespace X86ISA { public: BoundRange() : - X86Fault("Bound-Range", "#BR") + X86Fault("Bound-Range", "#BR", 5) {} }; @@ -256,7 +257,7 @@ namespace X86ISA { public: InvalidOpcode() : - X86Fault("Invalid-Opcode", "#UD") + X86Fault("Invalid-Opcode", "#UD", 6) {} }; @@ -264,7 +265,7 @@ namespace X86ISA { public: DeviceNotAvailable() : - X86Fault("Device-Not-Available", "#NM") + X86Fault("Device-Not-Available", "#NM", 7) {} }; @@ -272,7 +273,7 @@ namespace X86ISA { public: DoubleFault() : - X86Abort("Double-Fault", "#DF") + X86Abort("Double-Fault", "#DF", 8) {} }; @@ -280,7 +281,7 @@ namespace X86ISA { public: InvalidTSS() : - X86Fault("Invalid-TSS", "#TS") + X86Fault("Invalid-TSS", "#TS", 10) {} }; @@ -288,7 +289,7 @@ namespace X86ISA { public: SegmentNotPresent() : - X86Fault("Segment-Not-Present", "#NP") + X86Fault("Segment-Not-Present", "#NP", 11) {} }; @@ -296,7 +297,7 @@ namespace X86ISA { public: StackFault() : - X86Fault("Stack", "#SS") + X86Fault("Stack", "#SS", 12) {} }; @@ -304,7 +305,7 @@ namespace X86ISA { public: GeneralProtection(uint64_t _errorCode) : - X86Fault("General-Protection", "#GP", _errorCode) + X86Fault("General-Protection", "#GP", 13, _errorCode) {} }; @@ -312,7 +313,7 @@ namespace X86ISA { public: PageFault() : - X86Fault("Page-Fault", "#PF") + X86Fault("Page-Fault", "#PF", 14) {} }; @@ -320,7 +321,7 @@ namespace X86ISA { public: X87FpExceptionPending() : - X86Fault("x87 Floating-Point Exception Pending", "#MF") + X86Fault("x87 Floating-Point Exception Pending", "#MF", 16) {} }; @@ -328,7 +329,7 @@ namespace X86ISA { public: AlignmentCheck() : - X86Fault("Alignment-Check", "#AC") + X86Fault("Alignment-Check", "#AC", 17) {} }; @@ -336,7 +337,7 @@ namespace X86ISA { public: MachineCheck() : - X86Abort("Machine-Check", "#MC") + X86Abort("Machine-Check", "#MC", 18) {} }; @@ -344,7 +345,7 @@ namespace X86ISA { public: SIMDFloatingPointFault() : - X86Fault("SIMD Floating-Point", "#XF") + X86Fault("SIMD Floating-Point", "#XF", 19) {} }; @@ -352,7 +353,7 @@ namespace X86ISA { public: SecurityException() : - X86FaultBase("Security Exception", "#SX") + X86FaultBase("Security Exception", "#SX", 30) {} }; @@ -397,7 +398,7 @@ namespace X86ISA Addr vaddr; public: FakeITLBFault(Addr _vaddr) : - X86Fault("fake instruction tlb fault", "itlb"), + X86Fault("fake instruction tlb fault", "itlb", 0), vaddr(_vaddr) {} @@ -410,7 +411,7 @@ namespace X86ISA Addr vaddr; public: FakeDTLBFault(Addr _vaddr) : - X86Fault("fake data tlb fault", "dtlb"), + X86Fault("fake data tlb fault", "dtlb", 0), vaddr(_vaddr) {} -- cgit v1.2.3 From c0cd58812e23ff540c0ef80203f1baad16a9eda1 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 1 Feb 2009 17:04:21 -0800 Subject: X86: Touch up the interrupt entering microcode. --- src/arch/x86/isa/insts/romutil.py | 67 ++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 37 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/romutil.py b/src/arch/x86/isa/insts/romutil.py index 9645ee85d..2724637d1 100644 --- a/src/arch/x86/isa/insts/romutil.py +++ b/src/arch/x86/isa/insts/romutil.py @@ -59,25 +59,20 @@ def rom # Get the target CS descriptor using the selector in the gate # descriptor. # - srli t4, t1, 16, dataSize=8 - andi t5, t4, 0xF8, dataSize=8 - andi t0, t4, 0x4, flags=(EZF,), dataSize=2 + srli t10, t4, 16, dataSize=8 + andi t5, t10, 0xF8, dataSize=8 + andi t0, t10, 0x4, flags=(EZF,), dataSize=2 br rom_local_label("globalDescriptor"), flags=(CEZF,) ld t3, tsl, [1, t0, t5], dataSize=8, addressSize=8 br rom_local_label("processDescriptor") globalDescriptor: ld t3, tsg, [1, t0, t5], dataSize=8, addressSize=8 processDescriptor: - chks t4, t3, IntCSCheck, dataSize=8 - wrdl hs, t3, t4, dataSize=8 - - # Check that the target offset is in canonical form - wrdh t4, t1, t2, dataSize=8 - srli t4, t4, 47, dataSize=8 - addi t4, t4, 1, dataSize=8 - srli t4, t4, 1, dataSize=8 - or t4, t4, t4, flags=(EZF,), dataSize=2 - fault "new GeneralProtection(0)", flags=(nCEZF,) + chks t10, t3, IntCSCheck, dataSize=8 + wrdl hs, t3, t10, dataSize=8 + + # Stick the target offset in t9. + wrdh t9, t4, t2, dataSize=8 # @@ -85,27 +80,25 @@ processDescriptor: # # Record what we might set the stack selector to. - rdsel t6, ss - wrsel hs, t6 + rdsel t11, ss # Check if we're changing privelege level. At this point we can assume # we're going to a DPL that's less than or equal to the CPL. - rdattr t4, hs, dataSize=8 - srli t4, t4, 3, dataSize=8 - andi t4, t4, 3, dataSize=8 + rdattr t10, hs, dataSize=8 + srli t10, t10, 3, dataSize=8 + andi t10, t10, 3, dataSize=8 rdattr t5, cs, dataSize=8 srli t5, t5, 3, dataSize=8 - sub t5, t5, t4, dataSize=8 + sub t5, t5, t10, dataSize=8 andi t0, t5, 0x3, flags=(EZF,), dataSize=8 # We're going to change priviledge, so zero out the stack selector. We # need to let the IST have priority so we don't branch yet. - limm t4, 0 - wrsel hs, t4, flags=(nCEZF,) + wrsel t11, t0, flags=(nCEZF,) # Check the IST field of the gate descriptor - srli t4, t1, 32, dataSize=8 - andi t4, t4, 0x7, dataSize=8 - subi t0, t4, 1, flags=(ECF,), dataSize=8 + srli t10, t4, 32, dataSize=8 + andi t10, t10, 0x7, dataSize=8 + subi t0, t10, 1, flags=(ECF,), dataSize=8 br rom_local_label("istStackSwitch"), flags=(nCECF,) br rom_local_label("cplStackSwitch"), flags=(nCEZF,) @@ -134,42 +127,42 @@ stackSwitched: ## ## Point of no return. ## We're now going to irrevocably modify visible state. - ## Anything bad that's going to happen should have happened by now. + ## Anything bad that's going to happen should have happened by now or will + ## happen right now. ## + wrip t0, t9, dataSize=8 # # Build up the interrupt stack frame # + # Write out the contents of memory st t7, hs, [1, t0, t6], dataSize=8 limm t5, 0, dataSize=8 rdsel t5, cs, dataSize=2 st t5, hs, [1, t0, t6], 8, dataSize=8 - rflags t4, dataSize=8 - st t4, hs, [1, t0, t6], 16, dataSize=8 + rflags t10, dataSize=8 + st t10, hs, [1, t0, t6], 16, dataSize=8 st rsp, hs, [1, t0, t6], 24, dataSize=8 rdsel t5, ss, dataSize=2 st t5, hs, [1, t0, t6], 32, dataSize=8 # Set the stack segment mov rsp, rsp, t6, dataSize=8 - rdsel t7, hs, dataSize=2 - wrsel ss, t7, dataSize=2 + wrsel ss, t11, dataSize=2 # # Set up the target code segment # - srli t5, t1, 16, dataSize=8 + srli t5, t4, 16, dataSize=8 andi t5, t5, 0xFF, dataSize=8 wrdl cs, t3, t5, dataSize=8 wrsel cs, t5, dataSize=2 - wrdh t7, t1, t2, dataSize=8 - wrip t0, t7, dataSize=8 # - # Adjust rflags which is still in t4 from above + # Adjust rflags which is still in t10 from above # # Set IF to the lowest bit of the original gate type. @@ -177,16 +170,16 @@ stackSwitched: # Set the TF, NT, and RF bits. We'll flip them at the end. limm t6, (1 << 8) | (1 << 14) | (1 << 16) - or t4, t4, t6 - srli t5, t1, 40, dataSize=8 - srli t7, t4, 9, dataSize=8 + or t10, t10, t6 + srli t5, t4, 40, dataSize=8 + srli t7, t10, 9, dataSize=8 xor t5, t7, t5, dataSize=8 andi t5, t5, 1, dataSize=8 slli t5, t5, 9, dataSize=8 or t6, t5, t6, dataSize=8 # Put the results into rflags - wrflags t6, t4 + wrflags t6, t10 eret }; -- cgit v1.2.3 From 6b53b8387e1a0c05d878d47962c27bf7493b6d36 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 1 Feb 2009 17:05:37 -0800 Subject: X86: Make the chks microop check for the right int descriptor type. --- src/arch/x86/isa/insts/romutil.py | 11 +---------- src/arch/x86/isa/microops/regop.isa | 6 ++++++ 2 files changed, 7 insertions(+), 10 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/romutil.py b/src/arch/x86/isa/insts/romutil.py index 2724637d1..9b4a80d44 100644 --- a/src/arch/x86/isa/insts/romutil.py +++ b/src/arch/x86/isa/insts/romutil.py @@ -43,18 +43,9 @@ def rom ld t2, idtr, [1, t0, t4], 8, dataSize=8, addressSize=8 ld t4, idtr, [1, t0, t4], dataSize=8, addressSize=8 - # Check permissions + # Make sure the descriptor is a legal gate. chks t1, t4, IntGateCheck - mov t1, t1, t4, dataSize=8 - - # Check that it's the right type - srli t4, t1, 40, dataSize=8 - andi t4, t4, 0xe, dataSize=8 - xori t4, t4, 0xe, flags=(EZF,), dataSize=8 - fault "new GeneralProtection(0)", flags=(nCEZF,) - - # # Get the target CS descriptor using the selector in the gate # descriptor. diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 492452a51..200024690 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -1067,9 +1067,15 @@ let {{ "not implemented.\\n"); break; case SegIntGateCheck: + // Check permissions. if (desc.dpl < m5reg.cpl) { fault = new GeneralProtection((uint16_t)selector); } + // Make sure the gate's the right type. + if (m5reg.mode == LongMode && ((desc.type & 0xe) != 0xe) || + ((desc.type & 0x6) != 0x6)) { + fault = new GeneralProtection(0); + } break; case SegSSCheck: if (selector.si || selector.ti) { -- cgit v1.2.3 From 041402a949ac61c2b871ce0595fd6a406ea9629c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 1 Feb 2009 17:06:25 -0800 Subject: X86: Fix the upper bound on some ranges that were setting up the micro code assembler. --- src/arch/x86/isa/microasm.isa | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index f9e0a2fa8..bc49d3362 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -76,9 +76,9 @@ let {{ mainRom = X86MicrocodeRom('main ROM') assembler = MicroAssembler(X86Macroop, microopClasses, mainRom, Rom_Macroop) # Add in symbols for the microcode registers - for num in range(15): + for num in range(16): assembler.symbols["t%d" % num] = "NUM_INTREGS+%d" % num - for num in range(7): + for num in range(8): assembler.symbols["ufp%d" % num] = "FLOATREG_MICROFP(%d)" % num # Add in symbols for the segment descriptor registers for letter in ("C", "D", "E", "F", "G", "H", "S"): @@ -140,7 +140,7 @@ let {{ for reg in ('ax', 'bx', 'cx', 'dx', 'sp', 'bp', 'si', 'di'): assembler.symbols["r%s" % reg] = "INTREG_R%s" % reg.upper() - for reg in range(15): + for reg in range(16): assembler.symbols["cr%d" % reg] = "MISCREG_CR%d" % reg for flag in ('CF', 'PF', 'ECF', 'AF', 'EZF', 'ZF', 'SF', 'OF', \ -- cgit v1.2.3 From 9b4d1e0f9a08ff36651d12151d0b51c37fefd643 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 1 Feb 2009 17:07:18 -0800 Subject: X86: Distinguish between hardware and software interrupts/exceptions --- src/arch/x86/isa/microasm.isa | 2 +- src/arch/x86/isa/microops/regop.isa | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index bc49d3362..778754e0c 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -86,7 +86,7 @@ let {{ # Add in symbols for the various checks of segment selectors. for check in ("NoCheck", "CSCheck", "CallGateCheck", "IntGateCheck", - "SSCheck", "IretCheck", "IntCSCheck"): + "SoftIntGateCheck", "SSCheck", "IretCheck", "IntCSCheck"): assembler.symbols[check] = "Seg%s" % check for reg in ("TR", "IDTR"): diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 200024690..2e6160ec6 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -234,7 +234,7 @@ output header {{ enum SegmentSelectorCheck { SegNoCheck, SegCSCheck, SegCallGateCheck, SegIntGateCheck, - SegSSCheck, SegIretCheck, SegIntCSCheck + SegSoftIntGateCheck, SegSSCheck, SegIretCheck, SegIntCSCheck }; enum LongModeDescriptorType { @@ -1066,11 +1066,13 @@ let {{ panic("CS checks for far calls/jumps through call gates" "not implemented.\\n"); break; - case SegIntGateCheck: + case SegSoftIntGateCheck: // Check permissions. if (desc.dpl < m5reg.cpl) { fault = new GeneralProtection((uint16_t)selector); } + // Fall through on purpose + case SegIntGateCheck: // Make sure the gate's the right type. if (m5reg.mode == LongMode && ((desc.type & 0xe) != 0xe) || ((desc.type & 0x6) != 0x6)) { -- cgit v1.2.3 From 2f8cec849d49d2692665aec20a1cd441e743dae7 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 1 Feb 2009 17:07:43 -0800 Subject: X86: Make the long mode interrupt/exception microcode handle an error code. --- src/arch/x86/faults.cc | 1 + src/arch/x86/isa/insts/romutil.py | 72 ++++++++++++++++++++++++++------------- 2 files changed, 49 insertions(+), 24 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/faults.cc b/src/arch/x86/faults.cc index 18680899e..2ce377bdd 100644 --- a/src/arch/x86/faults.cc +++ b/src/arch/x86/faults.cc @@ -123,6 +123,7 @@ namespace X86ISA } tc->setIntReg(INTREG_MICRO(1), vector); tc->setIntReg(INTREG_MICRO(7), tc->readPC()); + tc->setIntReg(INTREG_MICRO(15), (uint64_t)(-1)); tc->setMicroPC(romMicroPC(entry)); tc->setNextMicroPC(romMicroPC(entry) + 1); } diff --git a/src/arch/x86/isa/insts/romutil.py b/src/arch/x86/isa/insts/romutil.py index 9b4a80d44..ea41d2ca8 100644 --- a/src/arch/x86/isa/insts/romutil.py +++ b/src/arch/x86/isa/insts/romutil.py @@ -26,13 +26,13 @@ # # Authors: Gabe Black -microcode = ''' +intCodeTemplate = ''' def rom { # This vectors the CPU into an interrupt handler in long mode. # On entry, t1 is set to the vector of the interrupt and t7 is the current # ip. We need that because rdip returns the next ip. - extern longModeInterrupt: + extern %(startLabel)s: # # Get the 64 bit interrupt or trap gate descriptor from the IDT @@ -44,7 +44,7 @@ def rom ld t4, idtr, [1, t0, t4], dataSize=8, addressSize=8 # Make sure the descriptor is a legal gate. - chks t1, t4, IntGateCheck + chks t1, t4, %(gateCheckType)s # # Get the target CS descriptor using the selector in the gate @@ -53,12 +53,12 @@ def rom srli t10, t4, 16, dataSize=8 andi t5, t10, 0xF8, dataSize=8 andi t0, t10, 0x4, flags=(EZF,), dataSize=2 - br rom_local_label("globalDescriptor"), flags=(CEZF,) + br rom_local_label("%(startLabel)s_globalDescriptor"), flags=(CEZF,) ld t3, tsl, [1, t0, t5], dataSize=8, addressSize=8 - br rom_local_label("processDescriptor") -globalDescriptor: + br rom_local_label("%(startLabel)s_processDescriptor") +%(startLabel)s_globalDescriptor: ld t3, tsg, [1, t0, t5], dataSize=8, addressSize=8 -processDescriptor: +%(startLabel)s_processDescriptor: chks t10, t3, IntCSCheck, dataSize=8 wrdl hs, t3, t10, dataSize=8 @@ -90,29 +90,29 @@ processDescriptor: srli t10, t4, 32, dataSize=8 andi t10, t10, 0x7, dataSize=8 subi t0, t10, 1, flags=(ECF,), dataSize=8 - br rom_local_label("istStackSwitch"), flags=(nCECF,) - br rom_local_label("cplStackSwitch"), flags=(nCEZF,) + br rom_local_label("%(startLabel)s_istStackSwitch"), flags=(nCECF,) + br rom_local_label("%(startLabel)s_cplStackSwitch"), flags=(nCEZF,) # If we're here, it's because the stack isn't being switched. - # Set t6 to the new rsp. - subi t6, rsp, 40, dataSize=8 - - # Align the stack + # Set t6 to the new aligned rsp. + mov t6, rsp, dataSize=8 andi t6, t6, 0xF0, dataSize=1 + subi t6, t6, 40 + %(errorCodeSize)d, dataSize=8 # Check that we can access everything we need to on the stack ldst t0, hs, [1, t0, t6], dataSize=8, addressSize=8 - ldst t0, hs, [1, t0, t6], 32, dataSize=8, addressSize=8 - br rom_local_label("stackSwitched") + ldst t0, hs, [1, t0, t6], \ + 32 + %(errorCodeSize)d, dataSize=8, addressSize=8 + br rom_local_label("%(startLabel)s_stackSwitched") -istStackSwitch: +%(startLabel)s_istStackSwitch: panic "IST based stack switching isn't implemented" - br rom_local_label("stackSwitched") + br rom_local_label("%(startLabel)s_stackSwitched") -cplStackSwitch: +%(startLabel)s_cplStackSwitch: panic "CPL change initiated stack switching isn't implemented" -stackSwitched: +%(startLabel)s_stackSwitched: ## @@ -130,15 +130,16 @@ stackSwitched: # Write out the contents of memory - st t7, hs, [1, t0, t6], dataSize=8 + %(errorCodeCode)s + st t7, hs, [1, t0, t6], %(errorCodeSize)d, dataSize=8, addressSize=8 limm t5, 0, dataSize=8 rdsel t5, cs, dataSize=2 - st t5, hs, [1, t0, t6], 8, dataSize=8 + st t5, hs, [1, t0, t6], 8 + %(errorCodeSize)d, dataSize=8, addressSize=8 rflags t10, dataSize=8 - st t10, hs, [1, t0, t6], 16, dataSize=8 - st rsp, hs, [1, t0, t6], 24, dataSize=8 + st t10, hs, [1, t0, t6], 16 + %(errorCodeSize)d, dataSize=8, addressSize=8 + st rsp, hs, [1, t0, t6], 24 + %(errorCodeSize)d, dataSize=8, addressSize=8 rdsel t5, ss, dataSize=2 - st t5, hs, [1, t0, t6], 32, dataSize=8 + st t5, hs, [1, t0, t6], 32 + %(errorCodeSize)d, dataSize=8, addressSize=8 # Set the stack segment mov rsp, rsp, t6, dataSize=8 @@ -174,7 +175,30 @@ stackSwitched: eret }; +''' +microcode = \ +intCodeTemplate % {\ + "startLabel" : "longModeInterrupt", + "gateCheckType" : "IntGateCheck", + "errorCodeSize" : 0, + "errorCodeCode" : "" +} + \ +intCodeTemplate % {\ + "startLabel" : "longModeSoftInterrupt", + "gateCheckType" : "SoftIntGateCheck", + "errorCodeSize" : 0, + "errorCodeCode" : "" +} + \ +intCodeTemplate % {\ + "startLabel" : "longModeInterruptWithError", + "gateCheckType" : "IntGateCheck", + "errorCodeSize" : 8, + "errorCodeCode" : ''' + st t15, hs, [1, t0, t6], dataSize=8, addressSize=8 + ''' +} + \ +''' def rom { # This vectors the CPU into an interrupt handler in legacy mode. -- cgit v1.2.3 From 923a14dde749ad6b1887ccea764439a167555772 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 1 Feb 2009 17:08:32 -0800 Subject: X86: Make the fault classes handle error codes better. --- src/arch/x86/faults.cc | 4 ++- src/arch/x86/faults.hh | 54 ++++++++++++++++++++++++++----------- src/arch/x86/isa/microops/regop.isa | 11 ++++---- 3 files changed, 46 insertions(+), 23 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/faults.cc b/src/arch/x86/faults.cc index 2ce377bdd..7702d98eb 100644 --- a/src/arch/x86/faults.cc +++ b/src/arch/x86/faults.cc @@ -123,7 +123,9 @@ namespace X86ISA } tc->setIntReg(INTREG_MICRO(1), vector); tc->setIntReg(INTREG_MICRO(7), tc->readPC()); - tc->setIntReg(INTREG_MICRO(15), (uint64_t)(-1)); + if (errorCode != (uint64_t)(-1)) { + tc->setIntReg(INTREG_MICRO(15), errorCode); + } tc->setMicroPC(romMicroPC(entry)); tc->setNextMicroPC(romMicroPC(entry) + 1); } diff --git a/src/arch/x86/faults.hh b/src/arch/x86/faults.hh index dc86d2cec..9c9cf3909 100644 --- a/src/arch/x86/faults.hh +++ b/src/arch/x86/faults.hh @@ -58,6 +58,7 @@ #ifndef __ARCH_X86_FAULTS_HH__ #define __ARCH_X86_FAULTS_HH__ +#include "base/bitunion.hh" #include "base/misc.hh" #include "sim/faults.hh" @@ -73,7 +74,7 @@ namespace X86ISA uint64_t errorCode; X86FaultBase(const char * _faultName, const char * _mnem, - const uint8_t _vector, uint64_t _errorCode = 0) : + const uint8_t _vector, uint64_t _errorCode = -1) : faultName(_faultName), mnem(_mnem), vector(_vector), errorCode(_errorCode) { @@ -107,7 +108,7 @@ namespace X86ISA { protected: X86Fault(const char * name, const char * mnem, - const uint8_t vector, uint64_t _errorCode = 0) : + const uint8_t vector, uint64_t _errorCode = -1) : X86FaultBase(name, mnem, vector, _errorCode) {} }; @@ -118,7 +119,7 @@ namespace X86ISA { protected: X86Trap(const char * name, const char * mnem, - const uint8_t vector, uint64_t _errorCode = 0) : + const uint8_t vector, uint64_t _errorCode = -1) : X86FaultBase(name, mnem, vector, _errorCode) {} @@ -132,7 +133,7 @@ namespace X86ISA { protected: X86Abort(const char * name, const char * mnem, - const uint8_t vector, uint64_t _errorCode = 0) : + const uint8_t vector, uint64_t _errorCode = -1) : X86FaultBase(name, mnem, vector, _errorCode) {} @@ -146,7 +147,7 @@ namespace X86ISA { protected: X86Interrupt(const char * name, const char * mnem, - const uint8_t _vector, uint64_t _errorCode = 0) : + const uint8_t _vector, uint64_t _errorCode = -1) : X86FaultBase(name, mnem, _vector, _errorCode) {} @@ -273,48 +274,69 @@ namespace X86ISA { public: DoubleFault() : - X86Abort("Double-Fault", "#DF", 8) + X86Abort("Double-Fault", "#DF", 8, 0) {} }; class InvalidTSS : public X86Fault { public: - InvalidTSS() : - X86Fault("Invalid-TSS", "#TS", 10) + InvalidTSS(uint32_t _errorCode) : + X86Fault("Invalid-TSS", "#TS", 10, _errorCode) {} }; class SegmentNotPresent : public X86Fault { public: - SegmentNotPresent() : - X86Fault("Segment-Not-Present", "#NP", 11) + SegmentNotPresent(uint32_t _errorCode) : + X86Fault("Segment-Not-Present", "#NP", 11, _errorCode) {} }; class StackFault : public X86Fault { public: - StackFault() : - X86Fault("Stack", "#SS", 12) + StackFault(uint32_t _errorCode) : + X86Fault("Stack", "#SS", 12, _errorCode) {} }; class GeneralProtection : public X86Fault { public: - GeneralProtection(uint64_t _errorCode) : + GeneralProtection(uint32_t _errorCode) : X86Fault("General-Protection", "#GP", 13, _errorCode) {} }; class PageFault : public X86Fault { + protected: + BitUnion32(PageFaultErrorCode) + Bitfield<0> present; + Bitfield<1> write; + Bitfield<2> user; + Bitfield<3> reserved; + Bitfield<4> fetch; + EndBitUnion(PageFaultErrorCode) + public: - PageFault() : - X86Fault("Page-Fault", "#PF", 14) + PageFault(uint32_t _errorCode) : + X86Fault("Page-Fault", "#PF", 14, _errorCode) {} + PageFault(bool present, bool write, bool user, + bool reserved, bool fetch) : + X86Fault("Page-Fault", "#PF", 14, 0) + { + PageFaultErrorCode code = 0; + code.present = present; + code.write = write; + code.user = user; + code.reserved = reserved; + code.fetch = fetch; + errorCode = code; + } }; class X87FpExceptionPending : public X86Fault @@ -329,7 +351,7 @@ namespace X86ISA { public: AlignmentCheck() : - X86Fault("Alignment-Check", "#AC", 17) + X86Fault("Alignment-Check", "#AC", 17, 0) {} }; diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 2e6160ec6..202bfc7f5 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -1069,7 +1069,7 @@ let {{ case SegSoftIntGateCheck: // Check permissions. if (desc.dpl < m5reg.cpl) { - fault = new GeneralProtection((uint16_t)selector); + fault = new GeneralProtection(selector); } // Fall through on purpose case SegIntGateCheck: @@ -1082,8 +1082,7 @@ let {{ case SegSSCheck: if (selector.si || selector.ti) { if (!desc.p) { - //FIXME This needs to also push the selector. - fault = new StackFault; + fault = new StackFault(selector); } } else { if ((m5reg.submode != SixtyFourBitMode || @@ -1092,7 +1091,7 @@ let {{ desc.type.codeOrData == 0 && desc.type.w) || (desc.dpl != m5reg.cpl) || (selector.rpl != m5reg.cpl)) { - fault = new GeneralProtection(psrc1 & 0xFFFF); + fault = new GeneralProtection(selector); } } break; @@ -1103,9 +1102,9 @@ let {{ !(desc.s == 1 && desc.type.codeOrData == 1) || (!desc.type.c && desc.dpl != selector.rpl) || (desc.type.c && desc.dpl > selector.rpl)) { - fault = new GeneralProtection(psrc1 & 0xFFFF); + fault = new GeneralProtection(selector); } else if (!desc.p) { - fault = new SegmentNotPresent; + fault = new SegmentNotPresent(selector); } break; } -- cgit v1.2.3 From 5a4eed5d34c814486086bf45d7750905de32d972 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 1 Feb 2009 17:09:08 -0800 Subject: X86: All x86 fault classes now attempt to do something useful. --- src/arch/x86/faults.cc | 57 ++++++++++++++++++++++++++++++--------- src/arch/x86/faults.hh | 35 +++++++++++++++--------- src/arch/x86/isa/insts/romutil.py | 2 +- 3 files changed, 69 insertions(+), 25 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/faults.cc b/src/arch/x86/faults.cc index 7702d98eb..1234e68e5 100644 --- a/src/arch/x86/faults.cc +++ b/src/arch/x86/faults.cc @@ -101,34 +101,67 @@ namespace X86ISA { #if FULL_SYSTEM - void X86Trap::invoke(ThreadContext * tc) - { - panic("X86 faults are not implemented!"); - } - - void X86Abort::invoke(ThreadContext * tc) - { - panic("X86 faults are not implemented!"); - } - - void X86Interrupt::invoke(ThreadContext * tc) + void X86FaultBase::invoke(ThreadContext * tc) { using namespace X86ISAInst::RomLabels; HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG); MicroPC entry; if (m5reg.mode == LongMode) { - entry = extern_label_longModeInterrupt; + if (isSoft()) { + entry = extern_label_longModeSoftInterrupt; + } else { + entry = extern_label_longModeInterrupt; + } } else { entry = extern_label_legacyModeInterrupt; } tc->setIntReg(INTREG_MICRO(1), vector); tc->setIntReg(INTREG_MICRO(7), tc->readPC()); if (errorCode != (uint64_t)(-1)) { + if (m5reg.mode == LongMode) { + entry = extern_label_longModeInterruptWithError; + } else { + panic("Legacy mode interrupts with error codes " + "aren't implementde.\n"); + } + // Software interrupts shouldn't have error codes. If one does, + // there would need to be microcode to set it up. + assert(!isSoft()); tc->setIntReg(INTREG_MICRO(15), errorCode); } tc->setMicroPC(romMicroPC(entry)); tc->setNextMicroPC(romMicroPC(entry) + 1); } + + void X86Trap::invoke(ThreadContext * tc) + { + X86FaultBase::invoke(tc); + // This is the same as a fault, but it happens -after- the instruction. + tc->setPC(tc->readNextPC()); + tc->setNextPC(tc->readNextNPC()); + tc->setNextNPC(tc->readNextNPC() + sizeof(MachInst)); + } + + void X86Abort::invoke(ThreadContext * tc) + { + panic("Abort exception!"); + } + + void PageFault::invoke(ThreadContext * tc) + { + HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG); + X86FaultBase::invoke(tc); + /* + * If something bad happens while trying to enter the page fault + * handler, I'm pretty sure that's a double fault and then all bets are + * off. That means it should be safe to update this state now. + */ + if (m5reg.mode == LongMode) { + tc->setMiscReg(MISCREG_CR2, addr); + } else { + tc->setMiscReg(MISCREG_CR2, (uint32_t)addr); + } + } void FakeITLBFault::invoke(ThreadContext * tc) { diff --git a/src/arch/x86/faults.hh b/src/arch/x86/faults.hh index 9c9cf3909..6a6dfc80a 100644 --- a/src/arch/x86/faults.hh +++ b/src/arch/x86/faults.hh @@ -95,11 +95,14 @@ namespace X86ISA return mnem; } - void - invoke(ThreadContext * tc) + virtual bool isSoft() { - panic("Unimplemented fault %s.\n", name()); + return false; } + +#if FULL_SYSTEM + void invoke(ThreadContext * tc); +#endif }; // Base class for x86 faults which behave as if the underlying instruction @@ -150,10 +153,6 @@ namespace X86ISA const uint8_t _vector, uint64_t _errorCode = -1) : X86FaultBase(name, mnem, _vector, _errorCode) {} - -#if FULL_SYSTEM - void invoke(ThreadContext * tc); -#endif }; class UnimpInstFault : public FaultBase @@ -321,13 +320,16 @@ namespace X86ISA Bitfield<4> fetch; EndBitUnion(PageFaultErrorCode) + Addr addr; + public: - PageFault(uint32_t _errorCode) : - X86Fault("Page-Fault", "#PF", 14, _errorCode) + PageFault(Addr _addr, uint32_t _errorCode) : + X86Fault("Page-Fault", "#PF", 14, _errorCode), addr(_addr) {} - PageFault(bool present, bool write, bool user, - bool reserved, bool fetch) : - X86Fault("Page-Fault", "#PF", 14, 0) + + PageFault(Addr _addr, bool present, bool write, + bool user, bool reserved, bool fetch) : + X86Fault("Page-Fault", "#PF", 14, 0), addr(_addr) { PageFaultErrorCode code = 0; code.present = present; @@ -337,6 +339,10 @@ namespace X86ISA code.fetch = fetch; errorCode = code; } + +#if FULL_SYSTEM + void invoke(ThreadContext * tc); +#endif }; class X87FpExceptionPending : public X86Fault @@ -410,6 +416,11 @@ namespace X86ISA SoftwareInterrupt(uint8_t _vector) : X86Interrupt("Software Interrupt", "INTn", _vector) {} + + bool isSoft() + { + return true; + } }; // These faults aren't part of the ISA definition. They trigger filling diff --git a/src/arch/x86/isa/insts/romutil.py b/src/arch/x86/isa/insts/romutil.py index ea41d2ca8..1345c3d05 100644 --- a/src/arch/x86/isa/insts/romutil.py +++ b/src/arch/x86/isa/insts/romutil.py @@ -95,7 +95,7 @@ def rom # If we're here, it's because the stack isn't being switched. # Set t6 to the new aligned rsp. - mov t6, rsp, dataSize=8 + mov t6, t6, rsp, dataSize=8 andi t6, t6, 0xF0, dataSize=1 subi t6, t6, 40 + %(errorCodeSize)d, dataSize=8 -- cgit v1.2.3 From e1798d063e6d794bd44ba329e1b3ba5ac1dca9a5 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 6 Feb 2009 20:55:50 -0800 Subject: Quell g++ 4.3 warning about operator ambiguity --- src/arch/x86/isa/microops/regop.isa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 202bfc7f5..567335b7f 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -1074,7 +1074,7 @@ let {{ // Fall through on purpose case SegIntGateCheck: // Make sure the gate's the right type. - if (m5reg.mode == LongMode && ((desc.type & 0xe) != 0xe) || + if ((m5reg.mode == LongMode && (desc.type & 0xe) != 0xe) || ((desc.type & 0x6) != 0x6)) { fault = new GeneralProtection(0); } -- cgit v1.2.3 From dd6ea8797fdfbe00331a17ab3ffade10bbcbde1f Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 9 Feb 2009 20:10:14 -0800 Subject: scons: Require SCons version 0.98.1 This allows me to clean things up so we are up to date with respect to deprecated features. There are many features scheduled for permanent failure in scons 2.0 and 0.98.1 provides the most compatability for that. It also paves the way for some nice new features that I will add soon --- src/arch/alpha/SConsopts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/alpha/SConsopts b/src/arch/alpha/SConsopts index 633eeb06f..b418e27c8 100644 --- a/src/arch/alpha/SConsopts +++ b/src/arch/alpha/SConsopts @@ -33,5 +33,5 @@ Import('*') all_isa_list.append('alpha') # Alpha can be compiled with Turbolaser support instead of Tsunami -sticky_opts.Add(BoolOption('ALPHA_TLASER', +sticky_vars.Add(BoolVariable('ALPHA_TLASER', 'Model Alpha TurboLaser platform (vs. Tsunami)', False)) -- cgit v1.2.3 From 20c5ec6e1cb52d9e0f39d50bb254bffda139c4ea Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 9 Feb 2009 20:10:15 -0800 Subject: copyright: This file need not have had the more restrictive copyright. --- src/arch/x86/SConsopts | 45 +++++++++------------------------------------ 1 file changed, 9 insertions(+), 36 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/SConsopts b/src/arch/x86/SConsopts index d8b7cbed1..f8b700271 100644 --- a/src/arch/x86/SConsopts +++ b/src/arch/x86/SConsopts @@ -3,43 +3,16 @@ # Copyright (c) 2007 The Hewlett-Packard Development Company # All rights reserved. # -# Redistribution and use of this software in source and binary forms, -# with or without modification, are permitted provided that the -# following conditions are met: -# -# The software must be used only for Non-Commercial Use which means any -# use which is NOT directed to receiving any direct monetary -# compensation for, or commercial advantage from such use. Illustrative -# examples of non-commercial use are academic research, personal study, -# teaching, education and corporate research & development. -# Illustrative examples of commercial use are distributing products for -# commercial advantage and providing services using the software for -# commercial advantage. -# -# If you wish to use this software or functionality therein that may be -# covered by patents for commercial use, please contact: -# Director of Intellectual Property Licensing -# Office of Strategy and Technology -# Hewlett-Packard Company -# 1501 Page Mill Road -# Palo Alto, California 94304 -# -# Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. Redistributions -# in binary form must reproduce the above copyright notice, this list of -# conditions and the following disclaimer in the documentation and/or -# other materials provided with the distribution. Neither the name of -# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its # contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. No right of -# sublicense is granted herewith. Derivatives of the software and -# output created using the software may be prepared, but only for -# Non-Commercial Uses. Derivatives of the software may be shared with -# others provided: (i) the others agree to abide by the list of -# conditions herein which includes the Non-Commercial Use restrictions; -# and (ii) such Derivatives of the software include the above copyright -# notice to acknowledge the contribution from this software where -# applicable, this list of conditions and the disclaimer below. +# this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -- cgit v1.2.3 From 36d9065f5f716f88c82a3f4e9a75fa040039aa0a Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Tue, 10 Feb 2009 15:49:29 -0800 Subject: syscall: Expose ioctl for MIPS --- src/arch/mips/linux/linux.hh | 18 +++++++++--------- src/arch/mips/linux/process.cc | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'src/arch') diff --git a/src/arch/mips/linux/linux.hh b/src/arch/mips/linux/linux.hh index 0d71a3c58..4667748fb 100644 --- a/src/arch/mips/linux/linux.hh +++ b/src/arch/mips/linux/linux.hh @@ -94,15 +94,15 @@ class MipsLinux : public Linux //@{ /// ioctl() command codes. - static const unsigned TIOCGETP = 0x7408; - static const unsigned TIOCSETP = 0x7409; - static const unsigned TIOCSETN = 0x740a; - static const unsigned TIOCSETC = 0x7411; - static const unsigned TIOCGETC = 0x7412; - static const unsigned FIONREAD = 0x467f; - static const unsigned TIOCISATTY = 0x5480; - static const unsigned TIOCGETS = 0x540d; - static const unsigned TIOCGETA = 0x7417; + static const unsigned TIOCGETP_ = 0x7408; + static const unsigned TIOCSETP_ = 0x7409; + static const unsigned TIOCSETN_ = 0x740a; + static const unsigned TIOCSETC_ = 0x7411; + static const unsigned TIOCGETC_ = 0x7412; + static const unsigned FIONREAD_ = 0x467f; + static const unsigned TIOCISATTY_ = 0x5480; + static const unsigned TIOCGETS_ = 0x540d; + static const unsigned TIOCGETA_ = 0x7417; //@} /// For table(). diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc index 56413484b..ce09e1628 100644 --- a/src/arch/mips/linux/process.cc +++ b/src/arch/mips/linux/process.cc @@ -175,7 +175,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 51 */ SyscallDesc("acct", unimplementedFunc), /* 52 */ SyscallDesc("umount2", unimplementedFunc), /* 53 */ SyscallDesc("lock", unimplementedFunc), - /* 54 */ SyscallDesc("ioctl", unimplementedFunc/*ioctlFunc*/), + /* 54 */ SyscallDesc("ioctl", ioctlFunc), /* 55 */ SyscallDesc("fcntl", fcntlFunc), /* 56 */ SyscallDesc("mpx", unimplementedFunc), /* 57 */ SyscallDesc("setpgid", unimplementedFunc), -- cgit v1.2.3 From 5d029ff11e88ba0ab89c88e500c5d0d2edaf744e Mon Sep 17 00:00:00 2001 From: Lisa Hsu Date: Mon, 16 Feb 2009 17:47:39 -0500 Subject: sycalls: implement mremap() and add DATA flag for getrlimit(). mremap has been tested on Alpha, compiles for the rest but not tested. I don't see why it wouldn't work though. --- src/arch/alpha/linux/process.cc | 2 +- src/arch/alpha/pagetable.hh | 7 +++++++ src/arch/mips/linux/process.cc | 2 +- src/arch/mips/tlb.hh | 3 +++ src/arch/sparc/linux/syscalls.cc | 4 ++-- src/arch/sparc/pagetable.hh | 6 ++++++ src/arch/x86/linux/syscalls.cc | 2 +- src/arch/x86/pagetable.hh | 6 ++++++ 8 files changed, 27 insertions(+), 5 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc index 6684051af..605e40627 100644 --- a/src/arch/alpha/linux/process.cc +++ b/src/arch/alpha/linux/process.cc @@ -463,7 +463,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 338 */ SyscallDesc("afs_syscall", unimplementedFunc), /* 339 */ SyscallDesc("uname", unameFunc), /* 340 */ SyscallDesc("nanosleep", unimplementedFunc), - /* 341 */ SyscallDesc("mremap", unimplementedFunc), + /* 341 */ SyscallDesc("mremap", mremapFunc), /* 342 */ SyscallDesc("nfsservctl", unimplementedFunc), /* 343 */ SyscallDesc("setresuid", unimplementedFunc), /* 344 */ SyscallDesc("getresuid", unimplementedFunc), diff --git a/src/arch/alpha/pagetable.hh b/src/arch/alpha/pagetable.hh index 6cf11be56..59df93bef 100644 --- a/src/arch/alpha/pagetable.hh +++ b/src/arch/alpha/pagetable.hh @@ -123,6 +123,13 @@ struct TlbEntry TlbEntry() {} + void + updateVaddr(Addr new_vaddr) + { + VAddr vaddr(new_vaddr); + tag = vaddr.vpn(); + } + Addr pageStart() { diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc index ce09e1628..9d9d33325 100644 --- a/src/arch/mips/linux/process.cc +++ b/src/arch/mips/linux/process.cc @@ -288,7 +288,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = { /* 164 */ SyscallDesc("sched_get_priority_min", unimplementedFunc), /* 165 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc), /* 166 */ SyscallDesc("nanosleep", unimplementedFunc), - /* 167 */ SyscallDesc("mremap", unimplementedFunc), + /* 167 */ SyscallDesc("mremap", mremapFunc), /* 168 */ SyscallDesc("accept", unimplementedFunc), /* 169 */ SyscallDesc("bind", unimplementedFunc), /* 170 */ SyscallDesc("connect", unimplementedFunc), diff --git a/src/arch/mips/tlb.hh b/src/arch/mips/tlb.hh index feb2509c5..4a8fc32ac 100644 --- a/src/arch/mips/tlb.hh +++ b/src/arch/mips/tlb.hh @@ -68,6 +68,9 @@ struct TlbEntry return _pageStart; } + void + updateVaddr(Addr new_vaddr) {} + void serialize(std::ostream &os) { SERIALIZE_SCALAR(_pageStart); diff --git a/src/arch/sparc/linux/syscalls.cc b/src/arch/sparc/linux/syscalls.cc index 2845f7bec..3e8c603cd 100644 --- a/src/arch/sparc/linux/syscalls.cc +++ b/src/arch/sparc/linux/syscalls.cc @@ -339,7 +339,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = { /* 247 */ SyscallDesc("sched_get_priority_min", unimplementedFunc), //32 bit /* 248 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc), //32 bit /* 249 */ SyscallDesc("nanosleep", unimplementedFunc), - /* 250 */ SyscallDesc("mremap", unimplementedFunc), //32 bit + /* 250 */ SyscallDesc("mremap", mremapFunc), //32 bit /* 251 */ SyscallDesc("_sysctl", unimplementedFunc), //32 bit /* 252 */ SyscallDesc("getsid", unimplementedFunc), //32 bit /* 253 */ SyscallDesc("fdatasync", unimplementedFunc), @@ -642,7 +642,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = { /* 247 */ SyscallDesc("sched_get_priority_min", unimplementedFunc), /* 248 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc), /* 249 */ SyscallDesc("nanosleep", unimplementedFunc), - /* 250 */ SyscallDesc("mremap", unimplementedFunc), + /* 250 */ SyscallDesc("mremap", mremapFunc), /* 251 */ SyscallDesc("_sysctl", unimplementedFunc), /* 252 */ SyscallDesc("getsid", unimplementedFunc), /* 253 */ SyscallDesc("fdatasync", unimplementedFunc), diff --git a/src/arch/sparc/pagetable.hh b/src/arch/sparc/pagetable.hh index ee4ca0c2c..cbdabe4c3 100644 --- a/src/arch/sparc/pagetable.hh +++ b/src/arch/sparc/pagetable.hh @@ -266,6 +266,12 @@ struct TlbEntry return pte.paddr(); } + void + updateVaddr(Addr new_vaddr) + { + range.va = new_vaddr; + } + void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); }; diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 754fb2eaf..ca35a5dd6 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -148,7 +148,7 @@ SyscallDesc X86LinuxProcess::syscallDescs[] = { /* 22 */ SyscallDesc("pipe", unimplementedFunc), /* 23 */ SyscallDesc("select", unimplementedFunc), /* 24 */ SyscallDesc("sched_yield", unimplementedFunc), - /* 25 */ SyscallDesc("mremap", unimplementedFunc), + /* 25 */ SyscallDesc("mremap", mremapFunc), /* 26 */ SyscallDesc("msync", unimplementedFunc), /* 27 */ SyscallDesc("mincore", unimplementedFunc), /* 28 */ SyscallDesc("madvise", unimplementedFunc), diff --git a/src/arch/x86/pagetable.hh b/src/arch/x86/pagetable.hh index e42693c03..1a7a945e4 100644 --- a/src/arch/x86/pagetable.hh +++ b/src/arch/x86/pagetable.hh @@ -113,6 +113,12 @@ namespace X86ISA TlbEntry(Addr asn, Addr _vaddr, Addr _paddr); TlbEntry() {} + void + updateVaddr(Addr new_vaddr) + { + vaddr = new_vaddr; + } + Addr pageStart() { return paddr; -- cgit v1.2.3 From 6c5afe6346b31edf6af245002c270a3c26618833 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Fri, 20 Feb 2009 11:02:48 -0500 Subject: Remove unnecessary building of FreeList/RenameMap in InOrder. Clean-up comments and O3 extensions InOrder Thread Context --- src/arch/mips/regfile.cc | 6 ------ 1 file changed, 6 deletions(-) (limited to 'src/arch') diff --git a/src/arch/mips/regfile.cc b/src/arch/mips/regfile.cc index e05bfe2df..663115bb6 100644 --- a/src/arch/mips/regfile.cc +++ b/src/arch/mips/regfile.cc @@ -199,12 +199,6 @@ MipsISA::copyRegs(ThreadContext *src, ThreadContext *dest) panic("Copy Regs Not Implemented Yet\n"); } -void -MipsISA::copyRegs(ThreadContext *src, ThreadContext *dest); -{ - panic("Copy Regs Not Implemented Yet\n"); -} - void MipsISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest) { -- cgit v1.2.3 From e8c1c3e72eb01409f7ec110eee3b32c07347bf6f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 23 Feb 2009 00:20:34 -0800 Subject: X86: Pass whether an access was a read/write/fetch so faults can behave accordingly. --- src/arch/x86/faults.cc | 4 ++-- src/arch/x86/faults.hh | 12 ++++++++---- src/arch/x86/pagetable_walker.cc | 4 +++- src/arch/x86/pagetable_walker.hh | 5 ++++- src/arch/x86/tlb.cc | 6 +++--- src/arch/x86/tlb.hh | 2 +- 6 files changed, 21 insertions(+), 12 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/faults.cc b/src/arch/x86/faults.cc index 1234e68e5..f01197f36 100644 --- a/src/arch/x86/faults.cc +++ b/src/arch/x86/faults.cc @@ -166,13 +166,13 @@ namespace X86ISA void FakeITLBFault::invoke(ThreadContext * tc) { // Start the page table walker. - tc->getITBPtr()->walk(tc, vaddr); + tc->getITBPtr()->walk(tc, vaddr, write, execute); } void FakeDTLBFault::invoke(ThreadContext * tc) { // Start the page table walker. - tc->getDTBPtr()->walk(tc, vaddr); + tc->getDTBPtr()->walk(tc, vaddr, write, execute); } #else // !FULL_SYSTEM diff --git a/src/arch/x86/faults.hh b/src/arch/x86/faults.hh index 6a6dfc80a..ae4314434 100644 --- a/src/arch/x86/faults.hh +++ b/src/arch/x86/faults.hh @@ -429,10 +429,12 @@ namespace X86ISA { protected: Addr vaddr; + bool write; + bool execute; public: - FakeITLBFault(Addr _vaddr) : + FakeITLBFault(Addr _vaddr, bool _write, bool _execute) : X86Fault("fake instruction tlb fault", "itlb", 0), - vaddr(_vaddr) + vaddr(_vaddr), write(_write), execute(_execute) {} void invoke(ThreadContext * tc); @@ -442,10 +444,12 @@ namespace X86ISA { protected: Addr vaddr; + bool write; + bool execute; public: - FakeDTLBFault(Addr _vaddr) : + FakeDTLBFault(Addr _vaddr, bool _write, bool _execute) : X86Fault("fake data tlb fault", "dtlb", 0), - vaddr(_vaddr) + vaddr(_vaddr), write(_write), execute(_execute) {} void invoke(ThreadContext * tc); diff --git a/src/arch/x86/pagetable_walker.cc b/src/arch/x86/pagetable_walker.cc index 564a04b38..b0b9209b5 100644 --- a/src/arch/x86/pagetable_walker.cc +++ b/src/arch/x86/pagetable_walker.cc @@ -319,11 +319,13 @@ Walker::doNext(PacketPtr &read, PacketPtr &write) } void -Walker::start(ThreadContext * _tc, Addr vaddr) +Walker::start(ThreadContext * _tc, Addr vaddr, bool _write, bool _execute) { assert(state == Ready); assert(!tc); tc = _tc; + execute = _execute; + write = _write; VAddr addr = vaddr; diff --git a/src/arch/x86/pagetable_walker.hh b/src/arch/x86/pagetable_walker.hh index 324f16f3c..de3f21195 100644 --- a/src/arch/x86/pagetable_walker.hh +++ b/src/arch/x86/pagetable_walker.hh @@ -95,7 +95,7 @@ namespace X86ISA void doNext(PacketPtr &read, PacketPtr &write); // Kick off the state machine. - void start(ThreadContext * _tc, Addr vaddr); + void start(ThreadContext * _tc, Addr vaddr, bool write, bool execute); protected: @@ -165,7 +165,10 @@ namespace X86ISA State nextState; int size; bool enableNX; + bool write, execute; TlbEntry entry; + + Fault pageFault(bool present); public: diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 1009386d7..34829848c 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -140,9 +140,9 @@ TLB::lookup(Addr va, bool update_lru) #if FULL_SYSTEM void -TLB::walk(ThreadContext * _tc, Addr vaddr) +TLB::walk(ThreadContext * _tc, Addr vaddr, bool write, bool execute) { - walker->start(_tc, vaddr); + walker->start(_tc, vaddr, write, execute); } #endif @@ -616,7 +616,7 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) // The vaddr already has the segment base applied. TlbEntry *entry = lookup(vaddr); if (!entry) { - return new TlbFault(vaddr); + return new TlbFault(vaddr, write, execute); } else { // Do paging protection checks. DPRINTF(TLB, "Entry found with paddr %#x, doing protection checks.\n", entry->paddr); diff --git a/src/arch/x86/tlb.hh b/src/arch/x86/tlb.hh index 89b965e97..56d635a90 100644 --- a/src/arch/x86/tlb.hh +++ b/src/arch/x86/tlb.hh @@ -119,7 +119,7 @@ namespace X86ISA Walker * walker; - void walk(ThreadContext * _tc, Addr vaddr); + void walk(ThreadContext * _tc, Addr vaddr, bool write, bool execute); #endif public: -- cgit v1.2.3 From 3fa9812e1d572cd06f95cec138b87d590160e4b4 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Mon, 23 Feb 2009 11:48:40 -0800 Subject: debug: Move debug_break into src/base --- src/arch/alpha/ev5.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index 7dc02a611..b3ef8f5d8 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -35,13 +35,13 @@ #include "arch/alpha/osfpal.hh" #include "arch/alpha/tlb.hh" #include "arch/alpha/kgdb.h" +#include "base/debug.hh" #include "base/remote_gdb.hh" #include "base/stats/events.hh" #include "config/full_system.hh" #include "cpu/base.hh" #include "cpu/simple_thread.hh" #include "cpu/thread_context.hh" -#include "sim/debug.hh" #include "sim/sim_exit.hh" namespace AlphaISA { -- cgit v1.2.3 From a1aba01a02a8c1261120de83d8fbfd6624f0cb17 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:15:34 -0800 Subject: CPU: Get rid of translate... functions from various interface classes. --- src/arch/x86/isa/microops/ldstop.isa | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index 8a0af14be..cdebe9613 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -454,7 +454,7 @@ let {{ Mem = Data; Base = merge(Base, EA - SegBase, addressSize); '''); - + defineMicroStoreOp('Cda', 'Mem = 0;', "Request::NO_ACCESS") iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp', {"code": "Data = merge(Data, EA, dataSize);", @@ -493,17 +493,6 @@ let {{ microopClasses["tia"] = TiaOp - iop = InstObjParams("cda", "Cda", 'X86ISA::LdStOp', - {"code": ''' - Addr paddr; - fault = xc->translateDataWriteAddr(EA, paddr, - dataSize, (1 << segment)); - ''', - "ea_code": calculateEA}) - header_output += MicroLeaDeclare.subst(iop) - decoder_output += MicroLdStOpConstructor.subst(iop) - exec_output += MicroLeaExecute.subst(iop) - class CdaOp(LdStOp): def __init__(self, segment, addr, disp = 0, dataSize="env.dataSize", addressSize="env.addressSize"): -- cgit v1.2.3 From 5605079b1f20bc7f6a4a80c8d1e4daabe7125270 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:15:44 -0800 Subject: ISA: Replace the translate functions in the TLBs with translateAtomic. --- src/arch/alpha/tlb.cc | 4 ++-- src/arch/alpha/tlb.hh | 4 ++-- src/arch/mips/tlb.cc | 4 ++-- src/arch/mips/tlb.hh | 5 +++-- src/arch/sparc/tlb.cc | 4 ++-- src/arch/sparc/tlb.hh | 4 ++-- src/arch/x86/tlb.cc | 11 ++++++----- src/arch/x86/tlb.hh | 6 +++--- 8 files changed, 22 insertions(+), 20 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc index be02293d6..82d410987 100644 --- a/src/arch/alpha/tlb.cc +++ b/src/arch/alpha/tlb.cc @@ -317,7 +317,7 @@ ITB::regStats() } Fault -ITB::translate(RequestPtr &req, ThreadContext *tc) +ITB::translateAtomic(RequestPtr &req, ThreadContext *tc) { //If this is a pal pc, then set PHYSICAL if (FULL_SYSTEM && PcPAL(req->getPC())) @@ -479,7 +479,7 @@ DTB::regStats() } Fault -DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) +DTB::translateAtomic(RequestPtr &req, ThreadContext *tc, bool write) { Addr pc = tc->readPC(); diff --git a/src/arch/alpha/tlb.hh b/src/arch/alpha/tlb.hh index 9267aa573..f5d2dbca9 100644 --- a/src/arch/alpha/tlb.hh +++ b/src/arch/alpha/tlb.hh @@ -131,7 +131,7 @@ class ITB : public TLB ITB(const Params *p); virtual void regStats(); - Fault translate(RequestPtr &req, ThreadContext *tc); + Fault translateAtomic(RequestPtr &req, ThreadContext *tc); }; class DTB : public TLB @@ -155,7 +155,7 @@ class DTB : public TLB DTB(const Params *p); virtual void regStats(); - Fault translate(RequestPtr &req, ThreadContext *tc, bool write); + Fault translateAtomic(RequestPtr &req, ThreadContext *tc, bool write); }; } // namespace AlphaISA diff --git a/src/arch/mips/tlb.cc b/src/arch/mips/tlb.cc index e91da4eea..db21c7919 100644 --- a/src/arch/mips/tlb.cc +++ b/src/arch/mips/tlb.cc @@ -310,7 +310,7 @@ TLB::regStats() } Fault -ITB::translate(RequestPtr &req, ThreadContext *tc) +ITB::translateAtomic(RequestPtr &req, ThreadContext *tc) { #if !FULL_SYSTEM Process * p = tc->getProcessPtr(); @@ -427,7 +427,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) } Fault -DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) +DTB::translateAtomic(RequestPtr &req, ThreadContext *tc, bool write) { #if !FULL_SYSTEM Process * p = tc->getProcessPtr(); diff --git a/src/arch/mips/tlb.hh b/src/arch/mips/tlb.hh index 4a8fc32ac..acb393116 100644 --- a/src/arch/mips/tlb.hh +++ b/src/arch/mips/tlb.hh @@ -145,7 +145,7 @@ class ITB : public TLB { typedef MipsTLBParams Params; ITB(const Params *p); - Fault translate(RequestPtr &req, ThreadContext *tc); + Fault translateAtomic(RequestPtr &req, ThreadContext *tc); }; class DTB : public TLB { @@ -153,7 +153,8 @@ class DTB : public TLB { typedef MipsTLBParams Params; DTB(const Params *p); - Fault translate(RequestPtr &req, ThreadContext *tc, bool write = false); + Fault translateAtomic(RequestPtr &req, ThreadContext *tc, + bool write = false); }; class UTB : public ITB, public DTB { diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index 9e5230674..683d916df 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -436,7 +436,7 @@ DTB::writeSfsr(Addr a, bool write, ContextType ct, } Fault -ITB::translate(RequestPtr &req, ThreadContext *tc) +ITB::translateAtomic(RequestPtr &req, ThreadContext *tc) { uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA); @@ -549,7 +549,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) } Fault -DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) +DTB::translateAtomic(RequestPtr &req, ThreadContext *tc, bool write) { /* * @todo this could really use some profiling and fixing to make diff --git a/src/arch/sparc/tlb.hh b/src/arch/sparc/tlb.hh index 504a40cbb..d563772e6 100644 --- a/src/arch/sparc/tlb.hh +++ b/src/arch/sparc/tlb.hh @@ -177,7 +177,7 @@ class ITB : public TLB cacheEntry = NULL; } - Fault translate(RequestPtr &req, ThreadContext *tc); + Fault translateAtomic(RequestPtr &req, ThreadContext *tc); private: void writeSfsr(bool write, ContextType ct, bool se, FaultTypes ft, int asi); @@ -199,7 +199,7 @@ class DTB : public TLB cacheEntry[1] = NULL; } - Fault translate(RequestPtr &req, ThreadContext *tc, bool write); + Fault translateAtomic(RequestPtr &req, ThreadContext *tc, bool write); #if FULL_SYSTEM Tick doMmuRegRead(ThreadContext *tc, Packet *pkt); Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt); diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 34829848c..33017a6aa 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -190,7 +190,8 @@ TLB::demapPage(Addr va, uint64_t asn) template Fault -TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) +TLB::translateAtomic(RequestPtr &req, ThreadContext *tc, + bool write, bool execute) { Addr vaddr = req->getVaddr(); DPRINTF(TLB, "Translating vaddr %#x.\n", vaddr); @@ -662,15 +663,15 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) }; Fault -DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) +DTB::translateAtomic(RequestPtr &req, ThreadContext *tc, bool write) { - return TLB::translate(req, tc, write, false); + return TLB::translateAtomic(req, tc, write, false); } Fault -ITB::translate(RequestPtr &req, ThreadContext *tc) +ITB::translateAtomic(RequestPtr &req, ThreadContext *tc) { - return TLB::translate(req, tc, false, true); + return TLB::translateAtomic(req, tc, false, true); } #if FULL_SYSTEM diff --git a/src/arch/x86/tlb.hh b/src/arch/x86/tlb.hh index 56d635a90..91bb4a761 100644 --- a/src/arch/x86/tlb.hh +++ b/src/arch/x86/tlb.hh @@ -138,7 +138,7 @@ namespace X86ISA EntryList entryList; template - Fault translate(RequestPtr &req, ThreadContext *tc, + Fault translateAtomic(RequestPtr &req, ThreadContext *tc, bool write, bool execute); public: @@ -159,7 +159,7 @@ namespace X86ISA _allowNX = false; } - Fault translate(RequestPtr &req, ThreadContext *tc); + Fault translateAtomic(RequestPtr &req, ThreadContext *tc); friend class DTB; }; @@ -172,7 +172,7 @@ namespace X86ISA { _allowNX = true; } - Fault translate(RequestPtr &req, ThreadContext *tc, bool write); + Fault translateAtomic(RequestPtr &req, ThreadContext *tc, bool write); #if FULL_SYSTEM Tick doMmuRegRead(ThreadContext *tc, Packet *pkt); Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt); -- cgit v1.2.3 From 1b336a8fe713dad2e77c5f973d9eb2f5fbcfb585 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:15:56 -0800 Subject: X86: Make the stupd microop not update registers in initiateAcc. --- src/arch/x86/isa/microops/ldstop.isa | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index cdebe9613..5697f781b 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -228,6 +228,7 @@ def template MicroStoreExecute {{ fault = write(xc, Mem, EA, (%(mem_flags)s) | segment); if(fault == NoFault) { + %(post_code)s; %(op_wb)s; } } @@ -252,20 +253,20 @@ def template MicroStoreInitiateAcc {{ if(fault == NoFault) { - fault = write(xc, Mem, EA, (%(mem_flags)s) | segment); - if(fault == NoFault) - { - %(op_wb)s; - } + write(xc, Mem, EA, (%(mem_flags)s) | segment); } return fault; } }}; def template MicroStoreCompleteAcc {{ - Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc, - Trace::InstRecord * traceData) const + Fault %(class_name)s::completeAcc(PacketPtr pkt, + %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const { + %(op_decl)s; + %(op_rd)s; + %(complete_code)s; + %(op_wb)s; return NoFault; } }}; @@ -419,7 +420,8 @@ let {{ defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);', 'StoreCheck') defineMicroLoadOp('Ldfp', 'FpData.uqw = Mem;') - def defineMicroStoreOp(mnemonic, code, mem_flags=0): + def defineMicroStoreOp(mnemonic, code, \ + postCode="", completeCode="", mem_flags=0): global header_output global decoder_output global exec_output @@ -430,6 +432,8 @@ let {{ # Build up the all register version of this micro op iop = InstObjParams(name, Name, 'X86ISA::LdStOp', {"code": code, + "post_code": postCode, + "complete_code": completeCode, "ea_code": calculateEA, "mem_flags": mem_flags}) header_output += MicroLdStOpDeclare.subst(iop) @@ -450,11 +454,10 @@ let {{ defineMicroStoreOp('St', 'Mem = Data;') defineMicroStoreOp('Stfp', 'Mem = FpData.uqw;') - defineMicroStoreOp('Stupd', ''' - Mem = Data; - Base = merge(Base, EA - SegBase, addressSize); - '''); - defineMicroStoreOp('Cda', 'Mem = 0;', "Request::NO_ACCESS") + defineMicroStoreOp('Stupd', 'Mem = Data;', + 'Base = merge(Base, EA - SegBase, addressSize);', + 'Base = merge(Base, pkt->req->getVaddr() - SegBase, addressSize);'); + defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS") iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp', {"code": "Data = merge(Data, EA, dataSize);", -- cgit v1.2.3 From 15940d06b5f6aabbe917a2a8c4cc4bb1cab991e2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:16:04 -0800 Subject: SPARC: Adjust a few instructions to not write registers in initiateAcc. --- src/arch/sparc/isa/decoder.isa | 18 ++++++++---------- src/arch/sparc/isa/formats/mem/basicmem.isa | 10 ++++++++++ src/arch/sparc/isa/formats/mem/util.isa | 14 +++++++++----- 3 files changed, 27 insertions(+), 15 deletions(-) (limited to 'src/arch') diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index c35b231ff..e34ca033f 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -1231,16 +1231,14 @@ decode OP default Unknown::unknown() 0x23: Load::lddf({{Frd.udw = Mem.udw;}}); 0x24: Store::stf({{Mem.uw = Frds.uw;}}); 0x25: decode RD { - 0x0: Store::stfsr({{fault = checkFpEnableFault(xc); - if (fault) - return fault; - Mem.uw = Fsr<31:0>; - Fsr = insertBits(Fsr,16,14,0);}}); - 0x1: Store::stxfsr({{fault = checkFpEnableFault(xc); - if (fault) - return fault; - Mem.udw = Fsr; - Fsr = insertBits(Fsr,16,14,0);}}); + 0x0: StoreFsr::stfsr({{fault = checkFpEnableFault(xc); + if (fault) + return fault; + Mem.uw = Fsr<31:0>;}}); + 0x1: StoreFsr::stxfsr({{fault = checkFpEnableFault(xc); + if (fault) + return fault; + Mem.udw = Fsr;}}); default: FailUnimpl::stfsrOther(); } 0x26: stqf({{fault = new FpDisabled;}}); diff --git a/src/arch/sparc/isa/formats/mem/basicmem.isa b/src/arch/sparc/isa/formats/mem/basicmem.isa index e3c043cf3..c7bb3e435 100644 --- a/src/arch/sparc/isa/formats/mem/basicmem.isa +++ b/src/arch/sparc/isa/formats/mem/basicmem.isa @@ -108,6 +108,16 @@ def format Store(code, *opt_flags) {{ StoreFuncs, '', name, Name, 0, opt_flags) }}; +def format StoreFsr(code, *opt_flags) {{ + code = filterDoubles(code) + (header_output, + decoder_output, + exec_output, + decode_block) = doMemFormat(code, + StoreFuncs, '', name, Name, 0, opt_flags, + 'Fsr = insertBits(Fsr,16,14,0);') +}}; + def format TwinLoad(code, *opt_flags) {{ (header_output, decoder_output, diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa index f2a2327ee..31efb9cf6 100644 --- a/src/arch/sparc/isa/formats/mem/util.isa +++ b/src/arch/sparc/isa/formats/mem/util.isa @@ -264,11 +264,6 @@ def template StoreInitiateAcc {{ fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem, EA, %(asi_val)s, 0); } - if(fault == NoFault) - { - //Write the resulting state to the execution context - %(op_wb)s; - } return fault; } }}; @@ -277,6 +272,15 @@ def template StoreCompleteAcc {{ Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const { + Fault fault = NoFault; + %(op_decl)s; + + %(op_rd)s; + %(postacc_code)s; + if (fault == NoFault) + { + %(op_wb)s; + } return NoFault; } }}; -- cgit v1.2.3 From 6ed47e94644f854baa33d1e9f367cc9eebd99abf Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:16:15 -0800 Subject: CPU: Implement translateTiming which defers to translateAtomic, and convert the timing simple CPU to use it. --- src/arch/alpha/tlb.cc | 20 ++++++++++++++++++-- src/arch/alpha/tlb.hh | 8 ++++++-- src/arch/mips/tlb.cc | 20 ++++++++++++++++++-- src/arch/mips/tlb.hh | 8 ++++++-- src/arch/sparc/tlb.cc | 20 ++++++++++++++++++-- src/arch/sparc/tlb.hh | 9 +++++++-- src/arch/x86/tlb.cc | 22 +++++++++++++++++++--- src/arch/x86/tlb.hh | 12 +++++++++--- 8 files changed, 101 insertions(+), 18 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc index 82d410987..2b0afacfe 100644 --- a/src/arch/alpha/tlb.cc +++ b/src/arch/alpha/tlb.cc @@ -317,7 +317,7 @@ ITB::regStats() } Fault -ITB::translateAtomic(RequestPtr &req, ThreadContext *tc) +ITB::translateAtomic(RequestPtr req, ThreadContext *tc) { //If this is a pal pc, then set PHYSICAL if (FULL_SYSTEM && PcPAL(req->getPC())) @@ -401,6 +401,14 @@ ITB::translateAtomic(RequestPtr &req, ThreadContext *tc) } +void +ITB::translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation) +{ + assert(translation); + translation->finish(translateAtomic(req, tc), req, tc, false); +} + /////////////////////////////////////////////////////////////////////// // // Alpha DTB @@ -479,7 +487,7 @@ DTB::regStats() } Fault -DTB::translateAtomic(RequestPtr &req, ThreadContext *tc, bool write) +DTB::translateAtomic(RequestPtr req, ThreadContext *tc, bool write) { Addr pc = tc->readPC(); @@ -616,6 +624,14 @@ DTB::translateAtomic(RequestPtr &req, ThreadContext *tc, bool write) return checkCacheability(req); } +void +DTB::translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation, bool write) +{ + assert(translation); + translation->finish(translateAtomic(req, tc, write), req, tc, write); +} + TlbEntry & TLB::index(bool advance) { diff --git a/src/arch/alpha/tlb.hh b/src/arch/alpha/tlb.hh index f5d2dbca9..877533797 100644 --- a/src/arch/alpha/tlb.hh +++ b/src/arch/alpha/tlb.hh @@ -131,7 +131,9 @@ class ITB : public TLB ITB(const Params *p); virtual void regStats(); - Fault translateAtomic(RequestPtr &req, ThreadContext *tc); + Fault translateAtomic(RequestPtr req, ThreadContext *tc); + void translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation); }; class DTB : public TLB @@ -155,7 +157,9 @@ class DTB : public TLB DTB(const Params *p); virtual void regStats(); - Fault translateAtomic(RequestPtr &req, ThreadContext *tc, bool write); + Fault translateAtomic(RequestPtr req, ThreadContext *tc, bool write); + void translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation, bool write); }; } // namespace AlphaISA diff --git a/src/arch/mips/tlb.cc b/src/arch/mips/tlb.cc index db21c7919..eac44eba8 100644 --- a/src/arch/mips/tlb.cc +++ b/src/arch/mips/tlb.cc @@ -310,7 +310,7 @@ TLB::regStats() } Fault -ITB::translateAtomic(RequestPtr &req, ThreadContext *tc) +ITB::translateAtomic(RequestPtr req, ThreadContext *tc) { #if !FULL_SYSTEM Process * p = tc->getProcessPtr(); @@ -426,8 +426,16 @@ ITB::translateAtomic(RequestPtr &req, ThreadContext *tc) #endif } +void +ITB::translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation) +{ + assert(translation); + translation->finish(translateAtomic(req, tc), req, tc, false); +} + Fault -DTB::translateAtomic(RequestPtr &req, ThreadContext *tc, bool write) +DTB::translateAtomic(RequestPtr req, ThreadContext *tc, bool write) { #if !FULL_SYSTEM Process * p = tc->getProcessPtr(); @@ -564,6 +572,14 @@ DTB::translateAtomic(RequestPtr &req, ThreadContext *tc, bool write) #endif } +void +DTB::translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation, bool write) +{ + assert(translation); + translation->finish(translateAtomic(req, tc, write), req, tc, write); +} + /////////////////////////////////////////////////////////////////////// // // Mips ITB diff --git a/src/arch/mips/tlb.hh b/src/arch/mips/tlb.hh index acb393116..1ab9d77e5 100644 --- a/src/arch/mips/tlb.hh +++ b/src/arch/mips/tlb.hh @@ -145,7 +145,9 @@ class ITB : public TLB { typedef MipsTLBParams Params; ITB(const Params *p); - Fault translateAtomic(RequestPtr &req, ThreadContext *tc); + Fault translateAtomic(RequestPtr req, ThreadContext *tc); + void translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation); }; class DTB : public TLB { @@ -153,8 +155,10 @@ class DTB : public TLB { typedef MipsTLBParams Params; DTB(const Params *p); - Fault translateAtomic(RequestPtr &req, ThreadContext *tc, + Fault translateAtomic(RequestPtr req, ThreadContext *tc, bool write = false); + void translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation, bool write = false); }; class UTB : public ITB, public DTB { diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index 683d916df..95ad0229e 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -436,7 +436,7 @@ DTB::writeSfsr(Addr a, bool write, ContextType ct, } Fault -ITB::translateAtomic(RequestPtr &req, ThreadContext *tc) +ITB::translateAtomic(RequestPtr req, ThreadContext *tc) { uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA); @@ -548,8 +548,16 @@ ITB::translateAtomic(RequestPtr &req, ThreadContext *tc) return NoFault; } +void +ITB::translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation) +{ + assert(translation); + translation->finish(translateAtomic(req, tc), req, tc, false); +} + Fault -DTB::translateAtomic(RequestPtr &req, ThreadContext *tc, bool write) +DTB::translateAtomic(RequestPtr req, ThreadContext *tc, bool write) { /* * @todo this could really use some profiling and fixing to make @@ -847,6 +855,14 @@ handleMmuRegAccess: return NoFault; }; +void +DTB::translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation, bool write) +{ + assert(translation); + translation->finish(translateAtomic(req, tc, write), req, tc, write); +} + #if FULL_SYSTEM Tick diff --git a/src/arch/sparc/tlb.hh b/src/arch/sparc/tlb.hh index d563772e6..4fe532d4a 100644 --- a/src/arch/sparc/tlb.hh +++ b/src/arch/sparc/tlb.hh @@ -177,7 +177,9 @@ class ITB : public TLB cacheEntry = NULL; } - Fault translateAtomic(RequestPtr &req, ThreadContext *tc); + Fault translateAtomic(RequestPtr req, ThreadContext *tc); + void translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation); private: void writeSfsr(bool write, ContextType ct, bool se, FaultTypes ft, int asi); @@ -199,7 +201,10 @@ class DTB : public TLB cacheEntry[1] = NULL; } - Fault translateAtomic(RequestPtr &req, ThreadContext *tc, bool write); + Fault translateAtomic(RequestPtr req, + ThreadContext *tc, bool write=false); + void translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation, bool write=false); #if FULL_SYSTEM Tick doMmuRegRead(ThreadContext *tc, Packet *pkt); Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt); diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 33017a6aa..a34922b44 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -190,7 +190,7 @@ TLB::demapPage(Addr va, uint64_t asn) template Fault -TLB::translateAtomic(RequestPtr &req, ThreadContext *tc, +TLB::translateAtomic(RequestPtr req, ThreadContext *tc, bool write, bool execute) { Addr vaddr = req->getVaddr(); @@ -663,17 +663,33 @@ TLB::translateAtomic(RequestPtr &req, ThreadContext *tc, }; Fault -DTB::translateAtomic(RequestPtr &req, ThreadContext *tc, bool write) +DTB::translateAtomic(RequestPtr req, ThreadContext *tc, bool write) { return TLB::translateAtomic(req, tc, write, false); } +void +DTB::translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation, bool write) +{ + assert(translation); + translation->finish(translateAtomic(req, tc, write), req, tc, write); +} + Fault -ITB::translateAtomic(RequestPtr &req, ThreadContext *tc) +ITB::translateAtomic(RequestPtr req, ThreadContext *tc) { return TLB::translateAtomic(req, tc, false, true); } +void +ITB::translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation) +{ + assert(translation); + translation->finish(translateAtomic(req, tc), req, tc, false); +} + #if FULL_SYSTEM Tick diff --git a/src/arch/x86/tlb.hh b/src/arch/x86/tlb.hh index 91bb4a761..56730983a 100644 --- a/src/arch/x86/tlb.hh +++ b/src/arch/x86/tlb.hh @@ -138,8 +138,10 @@ namespace X86ISA EntryList entryList; template - Fault translateAtomic(RequestPtr &req, ThreadContext *tc, + Fault translateAtomic(RequestPtr req, ThreadContext *tc, bool write, bool execute); + void translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation, bool write, bool execute); public: @@ -159,7 +161,9 @@ namespace X86ISA _allowNX = false; } - Fault translateAtomic(RequestPtr &req, ThreadContext *tc); + Fault translateAtomic(RequestPtr req, ThreadContext *tc); + void translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation); friend class DTB; }; @@ -172,7 +176,9 @@ namespace X86ISA { _allowNX = true; } - Fault translateAtomic(RequestPtr &req, ThreadContext *tc, bool write); + Fault translateAtomic(RequestPtr req, ThreadContext *tc, bool write); + void translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation, bool write); #if FULL_SYSTEM Tick doMmuRegRead(ThreadContext *tc, Packet *pkt); Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt); -- cgit v1.2.3 From 40fdba2454c219902db7ad1abd28593de8611c2b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:16:21 -0800 Subject: X86: Make the X86 TLB take advantage of delayed translations, and get rid of the fake TLB miss faults. --- src/arch/x86/faults.cc | 50 ------------ src/arch/x86/faults.hh | 32 -------- src/arch/x86/pagetable_walker.cc | 170 ++++++++++++++++++++++----------------- src/arch/x86/pagetable_walker.hh | 26 +++++- src/arch/x86/tlb.cc | 86 ++++++++++++++------ src/arch/x86/tlb.hh | 15 ++-- 6 files changed, 187 insertions(+), 192 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/faults.cc b/src/arch/x86/faults.cc index f01197f36..964eb0a7f 100644 --- a/src/arch/x86/faults.cc +++ b/src/arch/x86/faults.cc @@ -163,56 +163,6 @@ namespace X86ISA } } - void FakeITLBFault::invoke(ThreadContext * tc) - { - // Start the page table walker. - tc->getITBPtr()->walk(tc, vaddr, write, execute); - } - - void FakeDTLBFault::invoke(ThreadContext * tc) - { - // Start the page table walker. - tc->getDTBPtr()->walk(tc, vaddr, write, execute); - } - -#else // !FULL_SYSTEM - void FakeITLBFault::invoke(ThreadContext * tc) - { - DPRINTF(TLB, "Invoking an ITLB fault for address %#x at pc %#x.\n", - vaddr, tc->readPC()); - Process *p = tc->getProcessPtr(); - TlbEntry entry; - bool success = p->pTable->lookup(vaddr, entry); - if(!success) { - panic("Tried to execute unmapped address %#x.\n", vaddr); - } else { - Addr alignedVaddr = p->pTable->pageAlign(vaddr); - DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, - entry.pageStart()); - tc->getITBPtr()->insert(alignedVaddr, entry); - } - } - - void FakeDTLBFault::invoke(ThreadContext * tc) - { - DPRINTF(TLB, "Invoking an DTLB fault for address %#x at pc %#x.\n", - vaddr, tc->readPC()); - Process *p = tc->getProcessPtr(); - TlbEntry entry; - bool success = p->pTable->lookup(vaddr, entry); - if(!success) { - p->checkAndAllocNextPage(vaddr); - success = p->pTable->lookup(vaddr, entry); - } - if(!success) { - panic("Tried to access unmapped address %#x.\n", vaddr); - } else { - Addr alignedVaddr = p->pTable->pageAlign(vaddr); - DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, - entry.pageStart()); - tc->getDTBPtr()->insert(alignedVaddr, entry); - } - } #endif } // namespace X86ISA diff --git a/src/arch/x86/faults.hh b/src/arch/x86/faults.hh index ae4314434..3753e60e5 100644 --- a/src/arch/x86/faults.hh +++ b/src/arch/x86/faults.hh @@ -422,38 +422,6 @@ namespace X86ISA return true; } }; - - // These faults aren't part of the ISA definition. They trigger filling - // the tlb on a miss and are to take the place of a hardware table walker. - class FakeITLBFault : public X86Fault - { - protected: - Addr vaddr; - bool write; - bool execute; - public: - FakeITLBFault(Addr _vaddr, bool _write, bool _execute) : - X86Fault("fake instruction tlb fault", "itlb", 0), - vaddr(_vaddr), write(_write), execute(_execute) - {} - - void invoke(ThreadContext * tc); - }; - - class FakeDTLBFault : public X86Fault - { - protected: - Addr vaddr; - bool write; - bool execute; - public: - FakeDTLBFault(Addr _vaddr, bool _write, bool _execute) : - X86Fault("fake data tlb fault", "dtlb", 0), - vaddr(_vaddr), write(_write), execute(_execute) - {} - - void invoke(ThreadContext * tc); - }; }; #endif // __ARCH_X86_FAULTS_HH__ diff --git a/src/arch/x86/pagetable_walker.cc b/src/arch/x86/pagetable_walker.cc index b0b9209b5..fe3a4c3bb 100644 --- a/src/arch/x86/pagetable_walker.cc +++ b/src/arch/x86/pagetable_walker.cc @@ -84,7 +84,7 @@ BitUnion64(PageTableEntry) Bitfield<0> p; EndBitUnion(PageTableEntry) -void +Fault Walker::doNext(PacketPtr &read, PacketPtr &write) { assert(state != Ready && state != Waiting); @@ -106,11 +106,11 @@ Walker::doNext(PacketPtr &read, PacketPtr &write) pte.a = 1; entry.writable = pte.w; entry.user = pte.u; - if (badNX) - panic("NX violation!\n"); + if (badNX || !pte.p) { + stop(); + return pageFault(pte.p); + } entry.noExec = pte.nx; - if (!pte.p) - panic("Page at %#x not present!\n", entry.vaddr); nextState = LongPDP; break; case LongPDP: @@ -119,10 +119,10 @@ Walker::doNext(PacketPtr &read, PacketPtr &write) pte.a = 1; entry.writable = entry.writable && pte.w; entry.user = entry.user && pte.u; - if (badNX) - panic("NX violation!\n"); - if (!pte.p) - panic("Page at %#x not present!\n", entry.vaddr); + if (badNX || !pte.p) { + stop(); + return pageFault(pte.p); + } nextState = LongPD; break; case LongPD: @@ -130,10 +130,10 @@ Walker::doNext(PacketPtr &read, PacketPtr &write) pte.a = 1; entry.writable = entry.writable && pte.w; entry.user = entry.user && pte.u; - if (badNX) - panic("NX violation!\n"); - if (!pte.p) - panic("Page at %#x not present!\n", entry.vaddr); + if (badNX || !pte.p) { + stop(); + return pageFault(pte.p); + } if (!pte.ps) { // 4 KB page entry.size = 4 * (1 << 10); @@ -150,36 +150,32 @@ Walker::doNext(PacketPtr &read, PacketPtr &write) entry.patBit = bits(pte, 12); entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1); tlb->insert(entry.vaddr, entry); - nextState = Ready; - delete read->req; - delete read; - read = NULL; - return; + stop(); + return NoFault; } case LongPTE: doWrite = !pte.a; pte.a = 1; entry.writable = entry.writable && pte.w; entry.user = entry.user && pte.u; - if (badNX) - panic("NX violation!\n"); - if (!pte.p) - panic("Page at %#x not present!\n", entry.vaddr); + if (badNX || !pte.p) { + stop(); + return pageFault(pte.p); + } entry.paddr = (uint64_t)pte & (mask(40) << 12); entry.uncacheable = uncacheable; entry.global = pte.g; entry.patBit = bits(pte, 12); entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1); tlb->insert(entry.vaddr, entry); - nextState = Ready; - delete read->req; - delete read; - read = NULL; - return; + stop(); + return NoFault; case PAEPDP: nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.pael2 * size; - if (!pte.p) - panic("Page at %#x not present!\n", entry.vaddr); + if (!pte.p) { + stop(); + return pageFault(pte.p); + } nextState = PAEPD; break; case PAEPD: @@ -187,10 +183,10 @@ Walker::doNext(PacketPtr &read, PacketPtr &write) pte.a = 1; entry.writable = pte.w; entry.user = pte.u; - if (badNX) - panic("NX violation!\n"); - if (!pte.p) - panic("Page at %#x not present!\n", entry.vaddr); + if (badNX || !pte.p) { + stop(); + return pageFault(pte.p); + } if (!pte.ps) { // 4 KB page entry.size = 4 * (1 << 10); @@ -206,39 +202,35 @@ Walker::doNext(PacketPtr &read, PacketPtr &write) entry.patBit = bits(pte, 12); entry.vaddr = entry.vaddr & ~((2 * (1 << 20)) - 1); tlb->insert(entry.vaddr, entry); - nextState = Ready; - delete read->req; - delete read; - read = NULL; - return; + stop(); + return NoFault; } case PAEPTE: doWrite = !pte.a; pte.a = 1; entry.writable = entry.writable && pte.w; entry.user = entry.user && pte.u; - if (badNX) - panic("NX violation!\n"); - if (!pte.p) - panic("Page at %#x not present!\n", entry.vaddr); + if (badNX || !pte.p) { + stop(); + return pageFault(pte.p); + } entry.paddr = (uint64_t)pte & (mask(40) << 12); entry.uncacheable = uncacheable; entry.global = pte.g; entry.patBit = bits(pte, 7); entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1); tlb->insert(entry.vaddr, entry); - nextState = Ready; - delete read->req; - delete read; - read = NULL; - return; + stop(); + return NoFault; case PSEPD: doWrite = !pte.a; pte.a = 1; entry.writable = pte.w; entry.user = pte.u; - if (!pte.p) - panic("Page at %#x not present!\n", entry.vaddr); + if (!pte.p) { + stop(); + return pageFault(pte.p); + } if (!pte.ps) { // 4 KB page entry.size = 4 * (1 << 10); @@ -255,44 +247,40 @@ Walker::doNext(PacketPtr &read, PacketPtr &write) entry.patBit = bits(pte, 12); entry.vaddr = entry.vaddr & ~((4 * (1 << 20)) - 1); tlb->insert(entry.vaddr, entry); - nextState = Ready; - delete read->req; - delete read; - read = NULL; - return; + stop(); + return NoFault; } case PD: doWrite = !pte.a; pte.a = 1; entry.writable = pte.w; entry.user = pte.u; - if (!pte.p) - panic("Page at %#x not present!\n", entry.vaddr); + if (!pte.p) { + stop(); + return pageFault(pte.p); + } // 4 KB page entry.size = 4 * (1 << 10); nextRead = ((uint64_t)pte & (mask(20) << 12)) + vaddr.norml2 * size; nextState = PTE; break; - nextState = PTE; - break; case PTE: doWrite = !pte.a; pte.a = 1; entry.writable = pte.w; entry.user = pte.u; - if (!pte.p) - panic("Page at %#x not present!\n", entry.vaddr); + if (!pte.p) { + stop(); + return pageFault(pte.p); + } entry.paddr = (uint64_t)pte & (mask(20) << 12); entry.uncacheable = uncacheable; entry.global = pte.g; entry.patBit = bits(pte, 7); entry.vaddr = entry.vaddr & ~((4 * (1 << 10)) - 1); tlb->insert(entry.vaddr, entry); - nextState = Ready; - delete read->req; - delete read; - read = NULL; - return; + stop(); + return NoFault; default: panic("Unknown page table walker state %d!\n"); } @@ -316,16 +304,21 @@ Walker::doNext(PacketPtr &read, PacketPtr &write) delete oldRead->req; delete oldRead; } + return NoFault; } -void -Walker::start(ThreadContext * _tc, Addr vaddr, bool _write, bool _execute) +Fault +Walker::start(ThreadContext * _tc, BaseTLB::Translation *_translation, + RequestPtr _req, bool _write, bool _execute) { assert(state == Ready); assert(!tc); tc = _tc; + req = _req; + Addr vaddr = req->getVaddr(); execute = _execute; write = _write; + translation = _translation; VAddr addr = vaddr; @@ -339,6 +332,7 @@ Walker::start(ThreadContext * _tc, Addr vaddr, bool _write, bool _execute) // Do long mode. state = LongPML4; top = (cr3.longPdtb << 12) + addr.longl4 * size; + enableNX = efer.nxe; } else { // We're in some flavor of legacy mode. CR4 cr4 = tc->readMiscRegNoEffect(MISCREG_CR4); @@ -346,6 +340,7 @@ Walker::start(ThreadContext * _tc, Addr vaddr, bool _write, bool _execute) // Do legacy PAE. state = PAEPDP; top = (cr3.paePdtb << 5) + addr.pael3 * size; + enableNX = efer.nxe; } else { size = 4; top = (cr3.pdtb << 12) + addr.norml2 * size; @@ -356,14 +351,13 @@ Walker::start(ThreadContext * _tc, Addr vaddr, bool _write, bool _execute) // Do legacy non PSE. state = PD; } + enableNX = false; } } nextState = Ready; entry.vaddr = vaddr; - enableNX = efer.nxe; - Request::Flags flags = Request::PHYSICAL; if (cr3.pcd) flags.set(Request::UNCACHEABLE); @@ -372,13 +366,15 @@ Walker::start(ThreadContext * _tc, Addr vaddr, bool _write, bool _execute) read->allocate(); Enums::MemoryMode memMode = sys->getMemoryMode(); if (memMode == Enums::timing) { - tc->suspend(); + timingFault = NoFault; port.sendTiming(read); } else if (memMode == Enums::atomic) { + Fault fault; do { port.sendAtomic(read); PacketPtr write = NULL; - doNext(read, write); + fault = doNext(read, write); + assert(fault == NoFault || read == NULL); state = nextState; nextState = Ready; if (write) @@ -387,9 +383,11 @@ Walker::start(ThreadContext * _tc, Addr vaddr, bool _write, bool _execute) tc = NULL; state = Ready; nextState = Waiting; + return fault; } else { panic("Unrecognized memory system mode.\n"); } + return NoFault; } bool @@ -410,9 +408,10 @@ Walker::recvTiming(PacketPtr pkt) state = nextState; nextState = Ready; PacketPtr write = NULL; - doNext(pkt, write); + timingFault = doNext(pkt, write); state = Waiting; read = pkt; + assert(timingFault == NoFault || read == NULL); if (write) { writes.push_back(write); } @@ -421,10 +420,27 @@ Walker::recvTiming(PacketPtr pkt) sendPackets(); } if (inflight == 0 && read == NULL && writes.size() == 0) { - tc->activate(0); tc = NULL; state = Ready; nextState = Waiting; + if (timingFault == NoFault) { + /* + * Finish the translation. Now that we now the right entry is + * in the TLB, this should work with no memory accesses. + * There could be new faults unrelated to the table walk like + * permissions violations, so we'll need the return value as + * well. + */ + bool delayedResponse; + Fault fault = tlb->translate(req, tc, NULL, write, execute, + delayedResponse, true); + assert(!delayedResponse); + // Let the CPU continue. + translation->finish(fault, req, tc, write); + } else { + // There was a fault during the walk. Let the CPU know. + translation->finish(timingFault, req, tc, write); + } } } else if (pkt->wasNacked()) { pkt->reinitNacked(); @@ -525,6 +541,14 @@ Walker::getPort(const std::string &if_name, int idx) panic("No page table walker port named %s!\n", if_name); } +Fault +Walker::pageFault(bool present) +{ + HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG); + return new PageFault(entry.vaddr, present, write, + m5reg.cpl == 3, false, execute && enableNX); +} + } X86ISA::Walker * diff --git a/src/arch/x86/pagetable_walker.hh b/src/arch/x86/pagetable_walker.hh index de3f21195..992711acd 100644 --- a/src/arch/x86/pagetable_walker.hh +++ b/src/arch/x86/pagetable_walker.hh @@ -91,11 +91,22 @@ namespace X86ISA // if the machine is finished, or points to a packet to initiate // the next read. If any write is required to update an "accessed" // bit, write will point to a packet to do the write. Otherwise it - // will be NULL. - void doNext(PacketPtr &read, PacketPtr &write); + // will be NULL. The return value is whatever fault was incurred + // during this stage of the lookup. + Fault doNext(PacketPtr &read, PacketPtr &write); // Kick off the state machine. - void start(ThreadContext * _tc, Addr vaddr, bool write, bool execute); + Fault start(ThreadContext * _tc, BaseTLB::Translation *translation, + RequestPtr req, bool write, bool execute); + // Clean up after the state machine. + void + stop() + { + nextState = Ready; + delete read->req; + delete read; + read = NULL; + } protected: @@ -110,6 +121,11 @@ namespace X86ISA bool retrying; + /* + * The fault, if any, that's waiting to be delivered in timing mode. + */ + Fault timingFault; + /* * Functions for dealing with packets. */ @@ -156,16 +172,18 @@ namespace X86ISA // The TLB we're supposed to load. TLB * tlb; System * sys; + BaseTLB::Translation * translation; /* * State machine state. */ ThreadContext * tc; + RequestPtr req; State state; State nextState; int size; bool enableNX; - bool write, execute; + bool write, execute, user; TlbEntry entry; Fault pageFault(bool present); diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index a34922b44..3962cd607 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -72,6 +72,9 @@ #if FULL_SYSTEM #include "arch/x86/pagetable_walker.hh" +#else +#include "mem/page_table.hh" +#include "sim/process.hh" #endif namespace X86ISA { @@ -90,7 +93,7 @@ TLB::TLB(const Params *p) : BaseTLB(p), configAddress(0), size(p->size) #endif } -void +TlbEntry * TLB::insert(Addr vpn, TlbEntry &entry) { //TODO Deal with conflicting entries @@ -106,6 +109,7 @@ TLB::insert(Addr vpn, TlbEntry &entry) *newEntry = entry; newEntry->vaddr = vpn; entryList.push_front(newEntry); + return newEntry; } TLB::EntryList::iterator @@ -138,14 +142,6 @@ TLB::lookup(Addr va, bool update_lru) return *entry; } -#if FULL_SYSTEM -void -TLB::walk(ThreadContext * _tc, Addr vaddr, bool write, bool execute) -{ - walker->start(_tc, vaddr, write, execute); -} -#endif - void TLB::invalidateAll() { @@ -188,11 +184,12 @@ TLB::demapPage(Addr va, uint64_t asn) } } -template Fault -TLB::translateAtomic(RequestPtr req, ThreadContext *tc, - bool write, bool execute) +TLB::translate(RequestPtr req, ThreadContext *tc, + Translation *translation, bool write, bool execute, + bool &delayedResponse, bool timing) { + delayedResponse = false; Addr vaddr = req->getVaddr(); DPRINTF(TLB, "Translating vaddr %#x.\n", vaddr); uint32_t flags = req->getFlags(); @@ -617,14 +614,45 @@ TLB::translateAtomic(RequestPtr req, ThreadContext *tc, // The vaddr already has the segment base applied. TlbEntry *entry = lookup(vaddr); if (!entry) { - return new TlbFault(vaddr, write, execute); - } else { - // Do paging protection checks. - DPRINTF(TLB, "Entry found with paddr %#x, doing protection checks.\n", entry->paddr); - Addr paddr = entry->paddr | (vaddr & (entry->size-1)); - DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, paddr); - req->setPaddr(paddr); +#if FULL_SYSTEM + Fault fault = walker->start(tc, translation, req, + write, execute); + if (timing || fault != NoFault) { + // This gets ignored in atomic mode. + delayedResponse = true; + return fault; + } + entry = lookup(vaddr); + assert(entry); +#else + DPRINTF(TLB, "Handling a TLB miss for " + "address %#x at pc %#x.\n", + vaddr, tc->readPC()); + + Process *p = tc->getProcessPtr(); + TlbEntry newEntry; + bool success = p->pTable->lookup(vaddr, newEntry); + if(!success && !execute) { + p->checkAndAllocNextPage(vaddr); + success = p->pTable->lookup(vaddr, newEntry); + } + if(!success) { + panic("Tried to execute unmapped address %#x.\n", vaddr); + } else { + Addr alignedVaddr = p->pTable->pageAlign(vaddr); + DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, + newEntry.pageStart()); + entry = insert(alignedVaddr, newEntry); + } + DPRINTF(TLB, "Miss was serviced.\n"); +#endif } + // Do paging protection checks. + DPRINTF(TLB, "Entry found with paddr %#x, " + "doing protection checks.\n", entry->paddr); + Addr paddr = entry->paddr | (vaddr & (entry->size-1)); + DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, paddr); + req->setPaddr(paddr); } else { //Use the address which already has segmentation applied. DPRINTF(TLB, "Paging disabled.\n"); @@ -665,29 +693,41 @@ TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Fault DTB::translateAtomic(RequestPtr req, ThreadContext *tc, bool write) { - return TLB::translateAtomic(req, tc, write, false); + bool delayedResponse; + return TLB::translate(req, tc, NULL, write, + false, delayedResponse, false); } void DTB::translateTiming(RequestPtr req, ThreadContext *tc, Translation *translation, bool write) { + bool delayedResponse; assert(translation); - translation->finish(translateAtomic(req, tc, write), req, tc, write); + Fault fault = TLB::translate(req, tc, translation, + write, false, delayedResponse, true); + if (!delayedResponse) + translation->finish(fault, req, tc, write); } Fault ITB::translateAtomic(RequestPtr req, ThreadContext *tc) { - return TLB::translateAtomic(req, tc, false, true); + bool delayedResponse; + return TLB::translate(req, tc, NULL, false, + true, delayedResponse, false); } void ITB::translateTiming(RequestPtr req, ThreadContext *tc, Translation *translation) { + bool delayedResponse; assert(translation); - translation->finish(translateAtomic(req, tc), req, tc, false); + Fault fault = TLB::translate(req, tc, translation, + false, true, delayedResponse, true); + if (!delayedResponse) + translation->finish(fault, req, tc, false); } #if FULL_SYSTEM diff --git a/src/arch/x86/tlb.hh b/src/arch/x86/tlb.hh index 56730983a..2467bc472 100644 --- a/src/arch/x86/tlb.hh +++ b/src/arch/x86/tlb.hh @@ -87,8 +87,7 @@ namespace X86ISA class TLB : public BaseTLB { protected: - friend class FakeITLBFault; - friend class FakeDTLBFault; + friend class Walker; typedef std::list EntryList; @@ -118,8 +117,6 @@ namespace X86ISA protected: Walker * walker; - - void walk(ThreadContext * _tc, Addr vaddr, bool write, bool execute); #endif public: @@ -137,15 +134,13 @@ namespace X86ISA EntryList freeList; EntryList entryList; - template - Fault translateAtomic(RequestPtr req, ThreadContext *tc, - bool write, bool execute); - void translateTiming(RequestPtr req, ThreadContext *tc, - Translation *translation, bool write, bool execute); + Fault translate(RequestPtr req, ThreadContext *tc, + Translation *translation, bool write, bool execute, + bool &delayedResponse, bool timing); public: - void insert(Addr vpn, TlbEntry &entry); + TlbEntry * insert(Addr vpn, TlbEntry &entry); // Checkpointing virtual void serialize(std::ostream &os); -- cgit v1.2.3 From 7462cb0842b9963d137cb578be6a0f7c619712d1 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:16:34 -0800 Subject: X86: Fix the timing mode of the page table walker. --- src/arch/x86/pagetable_walker.cc | 47 +++++++++++++++++++--------------------- src/arch/x86/pagetable_walker.hh | 6 ++--- 2 files changed, 25 insertions(+), 28 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/pagetable_walker.cc b/src/arch/x86/pagetable_walker.cc index fe3a4c3bb..87f00dcbe 100644 --- a/src/arch/x86/pagetable_walker.cc +++ b/src/arch/x86/pagetable_walker.cc @@ -85,7 +85,7 @@ BitUnion64(PageTableEntry) EndBitUnion(PageTableEntry) Fault -Walker::doNext(PacketPtr &read, PacketPtr &write) +Walker::doNext(PacketPtr &write) { assert(state != Ready && state != Waiting); write = NULL; @@ -312,7 +312,6 @@ Walker::start(ThreadContext * _tc, BaseTLB::Translation *_translation, RequestPtr _req, bool _write, bool _execute) { assert(state == Ready); - assert(!tc); tc = _tc; req = _req; Addr vaddr = req->getVaddr(); @@ -366,21 +365,22 @@ Walker::start(ThreadContext * _tc, BaseTLB::Translation *_translation, read->allocate(); Enums::MemoryMode memMode = sys->getMemoryMode(); if (memMode == Enums::timing) { + nextState = state; + state = Waiting; timingFault = NoFault; - port.sendTiming(read); + sendPackets(); } else if (memMode == Enums::atomic) { Fault fault; do { port.sendAtomic(read); PacketPtr write = NULL; - fault = doNext(read, write); + fault = doNext(write); assert(fault == NoFault || read == NULL); state = nextState; nextState = Ready; if (write) port.sendAtomic(write); } while(read); - tc = NULL; state = Ready; nextState = Waiting; return fault; @@ -399,18 +399,18 @@ Walker::WalkerPort::recvTiming(PacketPtr pkt) bool Walker::recvTiming(PacketPtr pkt) { - inflight--; if (pkt->isResponse() && !pkt->wasNacked()) { + assert(inflight); + assert(state == Waiting); + assert(!read); + inflight--; if (pkt->isRead()) { - assert(inflight); - assert(state == Waiting); - assert(!read); state = nextState; nextState = Ready; PacketPtr write = NULL; - timingFault = doNext(pkt, write); - state = Waiting; read = pkt; + timingFault = doNext(write); + state = Waiting; assert(timingFault == NoFault || read == NULL); if (write) { writes.push_back(write); @@ -420,7 +420,6 @@ Walker::recvTiming(PacketPtr pkt) sendPackets(); } if (inflight == 0 && read == NULL && writes.size() == 0) { - tc = NULL; state = Ready; nextState = Waiting; if (timingFault == NoFault) { @@ -445,6 +444,7 @@ Walker::recvTiming(PacketPtr pkt) } else if (pkt->wasNacked()) { pkt->reinitNacked(); if (!port.sendTiming(pkt)) { + inflight--; retrying = true; if (pkt->isWrite()) { writes.push_back(pkt); @@ -452,8 +452,6 @@ Walker::recvTiming(PacketPtr pkt) assert(!read); read = pkt; } - } else { - inflight++; } } return true; @@ -507,27 +505,26 @@ Walker::sendPackets() //Reads always have priority if (read) { - if (!port.sendTiming(read)) { + PacketPtr pkt = read; + read = NULL; + inflight++; + if (!port.sendTiming(pkt)) { retrying = true; + read = pkt; + inflight--; return; - } else { - inflight++; - delete read->req; - delete read; - read = NULL; } } //Send off as many of the writes as we can. while (writes.size()) { PacketPtr write = writes.back(); + writes.pop_back(); + inflight++; if (!port.sendTiming(write)) { retrying = true; + writes.push_back(write); + inflight--; return; - } else { - inflight++; - delete write->req; - delete write; - writes.pop_back(); } } } diff --git a/src/arch/x86/pagetable_walker.hh b/src/arch/x86/pagetable_walker.hh index 992711acd..f73774a45 100644 --- a/src/arch/x86/pagetable_walker.hh +++ b/src/arch/x86/pagetable_walker.hh @@ -85,15 +85,15 @@ namespace X86ISA PSEPD, PD, PTE }; - // Act on the current state and determine what to do next. read - // should be the packet that just came back from a read and write + // Act on the current state and determine what to do next. The global + // read should be the packet that just came back from a read and write // should be NULL. When the function returns, read is either NULL // if the machine is finished, or points to a packet to initiate // the next read. If any write is required to update an "accessed" // bit, write will point to a packet to do the write. Otherwise it // will be NULL. The return value is whatever fault was incurred // during this stage of the lookup. - Fault doNext(PacketPtr &read, PacketPtr &write); + Fault doNext(PacketPtr &write); // Kick off the state machine. Fault start(ThreadContext * _tc, BaseTLB::Translation *translation, -- cgit v1.2.3 From 82288e7c3eea0fc62746d746e325c888a13c0a22 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:16:43 -0800 Subject: X86: Add makeAtomicResponse to the read/write functions of x86 devices. --- src/arch/x86/interrupts.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/interrupts.cc b/src/arch/x86/interrupts.cc index 29157b3f5..30c532c2b 100644 --- a/src/arch/x86/interrupts.cc +++ b/src/arch/x86/interrupts.cc @@ -221,6 +221,7 @@ X86ISA::Interrupts::read(PacketPtr pkt) "Reading Local APIC register %d at offset %#x as %#x.\n", reg, offset, val); pkt->setData(((uint8_t *)&val) + (offset & mask(3))); + pkt->makeAtomicResponse(); return latency; } @@ -238,6 +239,7 @@ X86ISA::Interrupts::write(PacketPtr pkt) "Writing Local APIC register %d at offset %#x as %#x.\n", reg, offset, gtoh(val)); setReg(reg, gtoh(val)); + pkt->makeAtomicResponse(); return latency; } void -- cgit v1.2.3 From 7b1cb74ac3c2b9a2a22f64ed88bd60fb353c76d7 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:16:54 -0800 Subject: X86: Add a check to chks which raises #GP(selector) if selector is NULL or not in the GDT. --- src/arch/x86/isa/microasm.isa | 3 ++- src/arch/x86/isa/microops/regop.isa | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index 778754e0c..354ee089e 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -86,7 +86,8 @@ let {{ # Add in symbols for the various checks of segment selectors. for check in ("NoCheck", "CSCheck", "CallGateCheck", "IntGateCheck", - "SoftIntGateCheck", "SSCheck", "IretCheck", "IntCSCheck"): + "SoftIntGateCheck", "SSCheck", "IretCheck", "IntCSCheck", + "TRCheck"): assembler.symbols[check] = "Seg%s" % check for reg in ("TR", "IDTR"): diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 567335b7f..9fb8b2f92 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -234,7 +234,8 @@ output header {{ enum SegmentSelectorCheck { SegNoCheck, SegCSCheck, SegCallGateCheck, SegIntGateCheck, - SegSoftIntGateCheck, SegSSCheck, SegIretCheck, SegIntCSCheck + SegSoftIntGateCheck, SegSSCheck, SegIretCheck, SegIntCSCheck, + SegTRCheck }; enum LongModeDescriptorType { @@ -1118,6 +1119,11 @@ let {{ "in legacy mode.\\n"); } break; + case SegTRCheck: + if (!selector.si || selector.ti) { + fault = new GeneralProtection(selector); + } + break; default: panic("Undefined segment check type.\\n"); } -- cgit v1.2.3 From 2f31643db52927d5c2e06d14e21846f1137d915a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:17:02 -0800 Subject: X86: Add a check to chks to verify a task state segment descriptor. --- src/arch/x86/isa/microasm.isa | 2 +- src/arch/x86/isa/microops/regop.isa | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index 354ee089e..d1025b137 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -87,7 +87,7 @@ let {{ # Add in symbols for the various checks of segment selectors. for check in ("NoCheck", "CSCheck", "CallGateCheck", "IntGateCheck", "SoftIntGateCheck", "SSCheck", "IretCheck", "IntCSCheck", - "TRCheck"): + "TRCheck", "TSSCheck"): assembler.symbols[check] = "Seg%s" % check for reg in ("TR", "IDTR"): diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 9fb8b2f92..0d569d403 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -235,7 +235,7 @@ output header {{ enum SegmentSelectorCheck { SegNoCheck, SegCSCheck, SegCallGateCheck, SegIntGateCheck, SegSoftIntGateCheck, SegSSCheck, SegIretCheck, SegIntCSCheck, - SegTRCheck + SegTRCheck, SegTSSCheck }; enum LongModeDescriptorType { @@ -1124,6 +1124,15 @@ let {{ fault = new GeneralProtection(selector); } break; + case SegTSSCheck: + if (!desc.p) { + fault = new SegmentNotPresent(selector); + } else if (!(desc.type == 0x9 || + (desc.type == 1 && + m5reg.mode != LongMode))) { + + } + break; default: panic("Undefined segment check type.\\n"); } -- cgit v1.2.3 From 08f3a126d540a88474a654720ecc7ceab9e0c246 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:17:08 -0800 Subject: X86: Fix segment limit checking. --- src/arch/x86/isa/microops/regop.isa | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 0d569d403..f21621e30 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -1192,10 +1192,12 @@ let {{ attr.dpl = desc.dpl; attr.defaultSize = desc.d; if (!desc.s) { - SegBaseDest = SegBaseDest; - SegLimitDest = SegLimitDest; - SegAttrDest = SegAttrDest; - panic("System segment encountered.\\n"); + // The expand down bit happens to be set for gates. + if (desc.type.e) { + panic("Gate descriptor encountered.\\n"); + } + attr.readable = 1; + attr.writable = 1; } else { if (!desc.p) panic("Segment not present.\\n"); @@ -1207,14 +1209,14 @@ let {{ attr.readable = 1; attr.writable = desc.type.w; } - Addr base = desc.baseLow | (desc.baseHigh << 24); - Addr limit = desc.limitLow | (desc.limitHigh << 16); - if (desc.g) - limit = (limit << 12) | mask(12); - SegBaseDest = base; - SegLimitDest = limit; - SegAttrDest = attr; } + Addr base = desc.baseLow | (desc.baseHigh << 24); + Addr limit = desc.limitLow | (desc.limitHigh << 16); + if (desc.g) + limit = (limit << 12) | mask(12); + SegBaseDest = base; + SegLimitDest = limit; + SegAttrDest = attr; } else { SegBaseDest = SegBaseDest; SegLimitDest = SegLimitDest; -- cgit v1.2.3 From aa7bc1be74beac674cc4feb4fece534de10379e3 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:17:14 -0800 Subject: X86: Implement the LTR instruction. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 2 +- src/arch/x86/isa/insts/system/segmentation.py | 48 +++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index 3cdfa48bb..67845fe8d 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -94,7 +94,7 @@ 0x0: sldt_Mw_or_Rv(); 0x1: str_Mw_or_Rv(); 0x2: lldt_Mw_or_Rv(); - 0x3: ltr_Mw_or_Rv(); + 0x3: Inst::LTR(Ew); 0x4: verr_Mw_or_Rv(); 0x5: verw_Mw_or_Rv(); //0x6: jmpe_Ev(); // IA-64 diff --git a/src/arch/x86/isa/insts/system/segmentation.py b/src/arch/x86/isa/insts/system/segmentation.py index 49d8eb110..c2bb46b7c 100644 --- a/src/arch/x86/isa/insts/system/segmentation.py +++ b/src/arch/x86/isa/insts/system/segmentation.py @@ -168,6 +168,54 @@ def macroop LIDT_16_P wrlimit idtr, t1 }; +def macroop LTR_R +{ + chks reg, t0, TRCheck + limm t4, 0 + srli t4, reg, 3, dataSize=2 + ldst t1, tsg, [8, t4, t0], dataSize=8 + ld t2, tsg, [8, t4, t0], 8, dataSize=8 + chks reg, t1, TSSCheck + wrdh t3, t1, t2 + wrdl tr, t1, reg + wrbase tr, t3, dataSize=8 + ori t1, t1, (1 << 9) + st t1, tsg, [8, t4, t0], dataSize=8 +}; + +def macroop LTR_M +{ + ld t5, seg, sib, disp, dataSize=2 + chks t5, t0, TRCheck + limm t4, 0 + srli t4, t5, 3, dataSize=2 + ldst t1, tsg, [8, t4, t0], dataSize=8 + ld t2, tsg, [8, t4, t0], 8, dataSize=8 + chks t5, t1, TSSCheck + wrdh t3, t1, t2 + wrdl tr, t1, t5 + wrbase tr, t3, dataSize=8 + ori t1, t1, (1 << 9) + st t1, tsg, [8, t4, t0], dataSize=8 +}; + +def macroop LTR_P +{ + rdip t7 + ld t5, seg, riprel, disp, dataSize=2 + chks t5, t0, TRCheck + limm t4, 0 + srli t4, t5, 3, dataSize=2 + ldst t1, tsg, [8, t4, t0], dataSize=8 + ld t2, tsg, [8, t4, t0], 8, dataSize=8 + chks t5, t1, TSSCheck + wrdh t3, t1, t2 + wrdl tr, t1, t5 + wrbase tr, t3, dataSize=8 + ori t1, t1, (1 << 9) + st t1, tsg, [8, t4, t0], dataSize=8 +}; + def macroop SWAPGS { rdval t1, kernel_gs_base, dataSize=8 -- cgit v1.2.3 From 99aa121fca8c893fb9f5b83b2568893033818ae3 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:17:19 -0800 Subject: X86: Make exceptions handle stack switching. --- src/arch/x86/isa/insts/romutil.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/romutil.py b/src/arch/x86/isa/insts/romutil.py index 1345c3d05..a39ba202f 100644 --- a/src/arch/x86/isa/insts/romutil.py +++ b/src/arch/x86/isa/insts/romutil.py @@ -80,29 +80,22 @@ def rom andi t10, t10, 3, dataSize=8 rdattr t5, cs, dataSize=8 srli t5, t5, 3, dataSize=8 - sub t5, t5, t10, dataSize=8 - andi t0, t5, 0x3, flags=(EZF,), dataSize=8 + andi t5, t5, 0x3, dataSize=8 + sub t0, t5, t10, flags=(EZF,), dataSize=8 # We're going to change priviledge, so zero out the stack selector. We # need to let the IST have priority so we don't branch yet. wrsel t11, t0, flags=(nCEZF,) # Check the IST field of the gate descriptor - srli t10, t4, 32, dataSize=8 - andi t10, t10, 0x7, dataSize=8 - subi t0, t10, 1, flags=(ECF,), dataSize=8 + srli t12, t4, 32, dataSize=8 + andi t12, t12, 0x7, dataSize=8 + subi t0, t12, 1, flags=(ECF,), dataSize=8 br rom_local_label("%(startLabel)s_istStackSwitch"), flags=(nCECF,) br rom_local_label("%(startLabel)s_cplStackSwitch"), flags=(nCEZF,) # If we're here, it's because the stack isn't being switched. # Set t6 to the new aligned rsp. mov t6, t6, rsp, dataSize=8 - andi t6, t6, 0xF0, dataSize=1 - subi t6, t6, 40 + %(errorCodeSize)d, dataSize=8 - - # Check that we can access everything we need to on the stack - ldst t0, hs, [1, t0, t6], dataSize=8, addressSize=8 - ldst t0, hs, [1, t0, t6], \ - 32 + %(errorCodeSize)d, dataSize=8, addressSize=8 br rom_local_label("%(startLabel)s_stackSwitched") %(startLabel)s_istStackSwitch: @@ -110,10 +103,18 @@ def rom br rom_local_label("%(startLabel)s_stackSwitched") %(startLabel)s_cplStackSwitch: - panic "CPL change initiated stack switching isn't implemented" + # Get the new rsp from the TSS + ld t6, tr, [8, t10, t0], 4, dataSize=8, addressSize=8 %(startLabel)s_stackSwitched: + andi t6, t6, 0xF0, dataSize=1 + subi t6, t6, 40 + %(errorCodeSize)d, dataSize=8 + + # Check that we can access everything we need to on the stack + ldst t0, hs, [1, t0, t6], dataSize=8, addressSize=8 + ldst t0, hs, [1, t0, t6], \ + 32 + %(errorCodeSize)d, dataSize=8, addressSize=8 ## ## Point of no return. -- cgit v1.2.3 From e4ede69b2f97206d836719839221531f3e01149e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:17:27 -0800 Subject: X86: Add a trace flag for the page table walker. --- src/arch/x86/SConscript | 2 ++ src/arch/x86/pagetable_walker.cc | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript index a57e388ea..8c1aec7a7 100644 --- a/src/arch/x86/SConscript +++ b/src/arch/x86/SConscript @@ -111,6 +111,8 @@ if env['TARGET_ISA'] == 'x86': if env['FULL_SYSTEM']: TraceFlag('LocalApic', "Local APIC debugging") + TraceFlag('PageTableWalker', \ + "Page table walker state machine debugging") SimObject('X86LocalApic.py') SimObject('X86System.py') diff --git a/src/arch/x86/pagetable_walker.cc b/src/arch/x86/pagetable_walker.cc index 87f00dcbe..f625cf4bd 100644 --- a/src/arch/x86/pagetable_walker.cc +++ b/src/arch/x86/pagetable_walker.cc @@ -101,6 +101,8 @@ Walker::doNext(PacketPtr &write) bool badNX = pte.nx && (!tlb->allowNX() || !enableNX); switch(state) { case LongPML4: + DPRINTF(PageTableWalker, + "Got long mode PML4 entry %#016x.\n", (uint64_t)pte); nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl3 * size; doWrite = !pte.a; pte.a = 1; @@ -114,6 +116,8 @@ Walker::doNext(PacketPtr &write) nextState = LongPDP; break; case LongPDP: + DPRINTF(PageTableWalker, + "Got long mode PDP entry %#016x.\n", (uint64_t)pte); nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.longl2 * size; doWrite = !pte.a; pte.a = 1; @@ -126,6 +130,8 @@ Walker::doNext(PacketPtr &write) nextState = LongPD; break; case LongPD: + DPRINTF(PageTableWalker, + "Got long mode PD entry %#016x.\n", (uint64_t)pte); doWrite = !pte.a; pte.a = 1; entry.writable = entry.writable && pte.w; @@ -154,6 +160,8 @@ Walker::doNext(PacketPtr &write) return NoFault; } case LongPTE: + DPRINTF(PageTableWalker, + "Got long mode PTE entry %#016x.\n", (uint64_t)pte); doWrite = !pte.a; pte.a = 1; entry.writable = entry.writable && pte.w; @@ -171,6 +179,8 @@ Walker::doNext(PacketPtr &write) stop(); return NoFault; case PAEPDP: + DPRINTF(PageTableWalker, + "Got legacy mode PAE PDP entry %#08x.\n", (uint32_t)pte); nextRead = ((uint64_t)pte & (mask(40) << 12)) + vaddr.pael2 * size; if (!pte.p) { stop(); @@ -179,6 +189,8 @@ Walker::doNext(PacketPtr &write) nextState = PAEPD; break; case PAEPD: + DPRINTF(PageTableWalker, + "Got legacy mode PAE PD entry %#08x.\n", (uint32_t)pte); doWrite = !pte.a; pte.a = 1; entry.writable = pte.w; @@ -206,6 +218,8 @@ Walker::doNext(PacketPtr &write) return NoFault; } case PAEPTE: + DPRINTF(PageTableWalker, + "Got legacy mode PAE PTE entry %#08x.\n", (uint32_t)pte); doWrite = !pte.a; pte.a = 1; entry.writable = entry.writable && pte.w; @@ -223,6 +237,8 @@ Walker::doNext(PacketPtr &write) stop(); return NoFault; case PSEPD: + DPRINTF(PageTableWalker, + "Got legacy mode PSE PD entry %#08x.\n", (uint32_t)pte); doWrite = !pte.a; pte.a = 1; entry.writable = pte.w; @@ -251,6 +267,8 @@ Walker::doNext(PacketPtr &write) return NoFault; } case PD: + DPRINTF(PageTableWalker, + "Got legacy mode PD entry %#08x.\n", (uint32_t)pte); doWrite = !pte.a; pte.a = 1; entry.writable = pte.w; @@ -265,6 +283,8 @@ Walker::doNext(PacketPtr &write) nextState = PTE; break; case PTE: + DPRINTF(PageTableWalker, + "Got legacy mode PTE entry %#08x.\n", (uint32_t)pte); doWrite = !pte.a; pte.a = 1; entry.writable = pte.w; @@ -541,6 +561,7 @@ Walker::getPort(const std::string &if_name, int idx) Fault Walker::pageFault(bool present) { + DPRINTF(PageTableWalker, "Raising page fault.\n"); HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG); return new PageFault(entry.vaddr, present, write, m5reg.cpl == 3, false, execute && enableNX); -- cgit v1.2.3 From fcad6e3b13410ab6c7263ce42b5e657c16f79e1d Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:17:38 -0800 Subject: X86: Add a wrattr microop. --- src/arch/x86/isa/microops/regop.isa | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index f21621e30..4434f9e74 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -1009,6 +1009,11 @@ let {{ SegSelDest = psrc1; ''' + class WrAttr(SegOp): + code = ''' + SegAttrDest = psrc1; + ''' + class Rdbase(SegOp): code = ''' DestReg = SegBaseSrc1; -- cgit v1.2.3 From dadc30b0a4dcf50c20c9d2b33890b94323fa0394 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:17:43 -0800 Subject: X86: Make the microcode assembler recognize r8-r15. --- src/arch/x86/isa/microasm.isa | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index d1025b137..fe1d38ff1 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -138,7 +138,8 @@ let {{ # like the internal segment above assembler.symbols["flatseg"] = "SEGMENT_REG_LS" - for reg in ('ax', 'bx', 'cx', 'dx', 'sp', 'bp', 'si', 'di'): + for reg in ('ax', 'bx', 'cx', 'dx', 'sp', 'bp', 'si', 'di', \ + '8', '9', '10', '11', '12', '13', '14', '15'): assembler.symbols["r%s" % reg] = "INTREG_R%s" % reg.upper() for reg in range(16): -- cgit v1.2.3 From 6325245e3ea7fae6609d0e9854c5ee7279140c02 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:17:49 -0800 Subject: X86: Implement the longmode versions of the syscall instruction. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 8 +- .../x86/isa/insts/general_purpose/system_calls.py | 107 ++++++++++++++++++++- 2 files changed, 111 insertions(+), 4 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index 67845fe8d..887b5bb14 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -254,7 +254,13 @@ } } #if FULL_SYSTEM - 0x05: syscall(); + 0x05: decode MODE_MODE { + 0x0: decode MODE_SUBMODE { + 0x0: Inst::SYSCALL_64(); + 0x1: Inst::SYSCALL_COMPAT(); + } + 0x1: Inst::SYSCALL_LEGACY(); + } #else 0x05: SyscallInst::syscall('xc->syscall(Rax)', IsSyscall); #endif diff --git a/src/arch/x86/isa/insts/general_purpose/system_calls.py b/src/arch/x86/isa/insts/general_purpose/system_calls.py index b3a57eca9..bb08282d2 100644 --- a/src/arch/x86/isa/insts/general_purpose/system_calls.py +++ b/src/arch/x86/isa/insts/general_purpose/system_calls.py @@ -53,14 +53,115 @@ # # Authors: Gabe Black -microcode = "" +microcode = ''' +def macroop SYSCALL_64 +{ + # All 1s. + limm t1, "(uint64_t)(-1)" + + # Save the next RIP. + rdip rcx + + # Stick rflags with RF masked into r11. + rflags t2 + limm t3, "~RFBit" + andi r11, t2, t3, dataSize=8 + + rdval t3, star + srli t3, t3, 32, dataSize=8 + andi t3, t3, 0xFC, dataSize=1 + + # Set up CS. + wrsel cs, t3 + wrbase cs, t0, dataSize=8 + wrlimit cs, t1, dataSize=4 + # Not writable, read/execute-able, not expandDown, + # dpl=0, defaultSize=0, long mode + limm t4, ((0 << 0) | (1 << 1) | (0 << 2) | \ + (0 << 3) | (0 << 5) | (1 << 6)) + wrattr cs, t4 + + # Set up SS. + addi t3, t3, 8 + wrsel ss, t3 + wrbase ss, t0, dataSize=8 + wrlimit ss, t1, dataSize=4 + # Writable, readable, not expandDown, + # dpl=0, defaultSize=0, not long mode + limm t4, ((1 << 0) | (1 << 1) | (0 << 2) | \ + (0 << 3) | (0 << 5) | (0 << 6)) + wrattr ss, t4 + + # Set the new rip. + rdval t7, lstar + wrip t0, t7 + + # Mask the flags against sf_mask and leave RF turned off. + rdval t3, sf_mask, dataSize=8 + xor t3, t3, t1, dataSize=8 + and t3, t3, r11, dataSize=8 + wrflags t3, t0 +}; + +def macroop SYSCALL_COMPAT +{ + # All 1s. + limm t1, "(uint64_t)(-1)" + + # Save the next RIP. + rdip rcx + + # Stick rflags with RF masked into r11. + rflags t2 + limm t3, "~RFBit" + andi r11, t2, t3, dataSize=8 + + rdval t3, star + srli t3, t3, 32, dataSize=8 + andi t3, t3, 0xFC, dataSize=1 + + # Set up CS. + wrsel cs, t3 + wrbase cs, t0, dataSize=8 + wrlimit cs, t1, dataSize=4 + # Not writable, read/execute-able, not expandDown, + # dpl=0, defaultSize=0, long mode + limm t4, ((0 << 0) | (1 << 1) | (0 << 2) | \ + (0 << 3) | (0 << 5) | (1 << 6)) + wrattr cs, t4 + + # Set up SS. + addi t3, t3, 8 + wrsel ss, t3 + wrbase ss, t0, dataSize=8 + wrlimit ss, t1, dataSize=4 + # Writable, readable, not expandDown, + # dpl=0, defaultSize=0, not long mode + limm t4, ((1 << 0) | (1 << 1) | (0 << 2) | \ + (0 << 3) | (0 << 5) | (0 << 6)) + wrattr ss, t4 + + # Set the new rip. + rdval t7, cstar + wrip t0, t7 + + # Mask the flags against sf_mask and leave RF turned off. + rdval t3, sf_mask, dataSize=8 + xor t3, t3, t1, dataSize=8 + and t3, t3, r11, dataSize=8 + wrflags t3, t0 +}; + +def macroop SYSCALL_LEGACY +{ + panic "The syscall instruction isn't implemented in legacy mode." +}; +''' #let {{ # class SYSENTER(Inst): # "GenFault ${new UnimpInstFault}" # class SYSEXIT(Inst): # "GenFault ${new UnimpInstFault}" -# class SYSCALL(Inst): -# "GenFault ${new UnimpInstFault}" # class SYSRET(Inst): # "GenFault ${new UnimpInstFault}" #}}; -- cgit v1.2.3 From eec3f49a57aca83e492e72b9cf55a8c6c6ebae73 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:17:54 -0800 Subject: X86: Implement the sysret instruction in long mode. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 12 +++- .../x86/isa/insts/general_purpose/system_calls.py | 72 +++++++++++++++++++++- 2 files changed, 79 insertions(+), 5 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index 887b5bb14..fa49c55d3 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -265,9 +265,15 @@ 0x05: SyscallInst::syscall('xc->syscall(Rax)', IsSyscall); #endif 0x06: clts(); - //sandpile.org says (AMD) after sysret, so I might want to check - //if that means amd64 or AMD machines - 0x07: loadall_or_sysret(); + 0x07: decode MODE_SUBMODE { + 0x0: decode OPSIZE { + // Return to 64 bit mode. + 0x8: Inst::SYSRET_TO_64(); + // Return to compatibility mode. + default: Inst::SYSRET_TO_COMPAT(); + } + default: Inst::SYSRET_NON_64(); + } } 0x01: decode OPCODE_OP_BOTTOM3 { 0x0: invd(); diff --git a/src/arch/x86/isa/insts/general_purpose/system_calls.py b/src/arch/x86/isa/insts/general_purpose/system_calls.py index bb08282d2..67607d5f8 100644 --- a/src/arch/x86/isa/insts/general_purpose/system_calls.py +++ b/src/arch/x86/isa/insts/general_purpose/system_calls.py @@ -156,12 +156,80 @@ def macroop SYSCALL_LEGACY { panic "The syscall instruction isn't implemented in legacy mode." }; + +def macroop SYSRET_TO_64 +{ + # All 1s. + limm t1, "(uint64_t)(-1)" + + rdval t3, star + srli t3, t3, 48, dataSize=8 + ori t3, t3, 3, dataSize=1 + + # Set rflags to r11 with RF and VM cleared. + limm t4, "~(RFBit | VMBit)" + and t4, t4, r11, dataSize=8 + wrflags t4, t0 + + # Set up CS. + addi t4, t3, 16, dataSize=8 + wrsel cs, t4 + wrbase cs, t0, dataSize=8 + wrlimit cs, t1, dataSize=4 + # Not writable, read/execute-able, not expandDown, + # dpl=3, defaultSize=0, long mode + limm t4, ((0 << 0) | (1 << 1) | (0 << 2) | \ + (3 << 3) | (0 << 5) | (1 << 6)) + wrattr cs, t4 + + # Only the selector is changed for SS. + addi t4, t3, 8, dataSize=8 + wrsel ss, t4 + + # Set the RIP back. + wrip rcx, t0, dataSize=8 +}; + +def macroop SYSRET_TO_COMPAT +{ + # All 1s. + limm t1, "(uint64_t)(-1)" + + rdval t3, star + srli t3, t3, 48, dataSize=8 + ori t3, t3, 3, dataSize=1 + + # Set rflags to r11 with RF and VM cleared. + limm t4, "~(RFBit | VMBit)" + and t4, t4, r11, dataSize=8 + wrflags t4, t0 + + # Set up CS. + wrsel cs, t3 + wrbase cs, t0, dataSize=8 + wrlimit cs, t1, dataSize=4 + # Not writable, read/execute-able, not expandDown, + # dpl=3, defaultSize=1, not long mode + limm t4, ((0 << 0) | (1 << 1) | (0 << 2) | \ + (3 << 3) | (1 << 5) | (0 << 6)) + wrattr cs, t4 + + # Only the selector is changed for SS. + addi t4, t3, 8, dataSize=8 + wrsel ss, t4 + + # Set the RIP back. + wrip rcx, t0, dataSize=8 +}; + +def macroop SYSRET_NON_64 +{ + panic "The sysret instruction isn't implemented in legacy mode." +}; ''' #let {{ # class SYSENTER(Inst): # "GenFault ${new UnimpInstFault}" # class SYSEXIT(Inst): # "GenFault ${new UnimpInstFault}" -# class SYSRET(Inst): -# "GenFault ${new UnimpInstFault}" #}}; -- cgit v1.2.3 From 1cedc748d413513c1bb98a454cc035f35b30f0f9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:17:59 -0800 Subject: X86: Add a trace flag for tracing faults. --- src/arch/x86/SConscript | 1 + src/arch/x86/faults.cc | 24 +++++++++++++++++++++++- src/arch/x86/faults.hh | 8 +++++++- 3 files changed, 31 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript index 8c1aec7a7..0e13d3104 100644 --- a/src/arch/x86/SConscript +++ b/src/arch/x86/SConscript @@ -113,6 +113,7 @@ if env['TARGET_ISA'] == 'x86': TraceFlag('LocalApic', "Local APIC debugging") TraceFlag('PageTableWalker', \ "Page table walker state machine debugging") + TraceFlag('Faults', "Trace all faults/exceptions/traps") SimObject('X86LocalApic.py') SimObject('X86System.py') diff --git a/src/arch/x86/faults.cc b/src/arch/x86/faults.cc index 964eb0a7f..b81400cc3 100644 --- a/src/arch/x86/faults.cc +++ b/src/arch/x86/faults.cc @@ -103,6 +103,8 @@ namespace X86ISA #if FULL_SYSTEM void X86FaultBase::invoke(ThreadContext * tc) { + Addr pc = tc->readPC(); + DPRINTF(Faults, "RIP %#x: vector %d: %s\n", pc, vector, describe()); using namespace X86ISAInst::RomLabels; HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG); MicroPC entry; @@ -116,7 +118,7 @@ namespace X86ISA entry = extern_label_legacyModeInterrupt; } tc->setIntReg(INTREG_MICRO(1), vector); - tc->setIntReg(INTREG_MICRO(7), tc->readPC()); + tc->setIntReg(INTREG_MICRO(7), pc); if (errorCode != (uint64_t)(-1)) { if (m5reg.mode == LongMode) { entry = extern_label_longModeInterruptWithError; @@ -132,6 +134,18 @@ namespace X86ISA tc->setMicroPC(romMicroPC(entry)); tc->setNextMicroPC(romMicroPC(entry) + 1); } + + std::string + X86FaultBase::describe() const + { + std::stringstream ss; + ccprintf(ss, "%s", mnemonic()); + if (errorCode != (uint64_t)(-1)) { + ccprintf(ss, "(%#x)", errorCode); + } + + return ss.str(); + } void X86Trap::invoke(ThreadContext * tc) { @@ -163,6 +177,14 @@ namespace X86ISA } } + std::string + PageFault::describe() const + { + std::stringstream ss; + ccprintf(ss, "%s at %#x", X86FaultBase::describe(), addr); + return ss.str(); + } + #endif } // namespace X86ISA diff --git a/src/arch/x86/faults.hh b/src/arch/x86/faults.hh index 3753e60e5..cb1a3f18a 100644 --- a/src/arch/x86/faults.hh +++ b/src/arch/x86/faults.hh @@ -62,6 +62,8 @@ #include "base/misc.hh" #include "sim/faults.hh" +#include + namespace X86ISA { // Base class for all x86 "faults" where faults is in the m5 sense @@ -102,6 +104,8 @@ namespace X86ISA #if FULL_SYSTEM void invoke(ThreadContext * tc); + + virtual std::string describe() const; #endif }; @@ -342,6 +346,8 @@ namespace X86ISA #if FULL_SYSTEM void invoke(ThreadContext * tc); + + virtual std::string describe() const; #endif }; @@ -414,7 +420,7 @@ namespace X86ISA { public: SoftwareInterrupt(uint8_t _vector) : - X86Interrupt("Software Interrupt", "INTn", _vector) + X86Interrupt("Software Interrupt", "#INTR", _vector) {} bool isSoft() -- cgit v1.2.3 From 710b43dfbdbbaf0588d182ce0bc82a0b7db0b550 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:18:06 -0800 Subject: X86: Implement inUserMode for x86. --- src/arch/x86/utility.hh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/utility.hh b/src/arch/x86/utility.hh index 477a76e0b..6f0812a6a 100644 --- a/src/arch/x86/utility.hh +++ b/src/arch/x86/utility.hh @@ -93,7 +93,12 @@ namespace X86ISA static inline bool inUserMode(ThreadContext *tc) { - return false; +#if FULL_SYSTEM + HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG); + return m5reg.cpl == 3; +#else + return true; +#endif } inline bool isCallerSaveIntegerRegister(unsigned int reg) { -- cgit v1.2.3 From 897c3748925e83301027d85dbc4c0479d972fda4 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:18:16 -0800 Subject: X86: Move where CS is set so CPL checks work out. --- src/arch/x86/isa/insts/romutil.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/romutil.py b/src/arch/x86/isa/insts/romutil.py index a39ba202f..93276addc 100644 --- a/src/arch/x86/isa/insts/romutil.py +++ b/src/arch/x86/isa/insts/romutil.py @@ -124,6 +124,18 @@ def rom ## wrip t0, t9, dataSize=8 + # + # Set up the target code segment. Do this now so we have the right + # permissions when setting up the stack frame. + # + srli t5, t4, 16, dataSize=8 + andi t5, t5, 0xFF, dataSize=8 + wrdl cs, t3, t5, dataSize=8 + # Tuck away the old CS for use below + limm t10, 0, dataSize=8 + rdsel t10, cs, dataSize=2 + wrsel cs, t5, dataSize=2 + # # Build up the interrupt stack frame @@ -133,9 +145,7 @@ def rom # Write out the contents of memory %(errorCodeCode)s st t7, hs, [1, t0, t6], %(errorCodeSize)d, dataSize=8, addressSize=8 - limm t5, 0, dataSize=8 - rdsel t5, cs, dataSize=2 - st t5, hs, [1, t0, t6], 8 + %(errorCodeSize)d, dataSize=8, addressSize=8 + st t10, hs, [1, t0, t6], 8 + %(errorCodeSize)d, dataSize=8, addressSize=8 rflags t10, dataSize=8 st t10, hs, [1, t0, t6], 16 + %(errorCodeSize)d, dataSize=8, addressSize=8 st rsp, hs, [1, t0, t6], 24 + %(errorCodeSize)d, dataSize=8, addressSize=8 @@ -146,14 +156,6 @@ def rom mov rsp, rsp, t6, dataSize=8 wrsel ss, t11, dataSize=2 - # - # Set up the target code segment - # - srli t5, t4, 16, dataSize=8 - andi t5, t5, 0xFF, dataSize=8 - wrdl cs, t3, t5, dataSize=8 - wrsel cs, t5, dataSize=2 - # # Adjust rflags which is still in t10 from above # -- cgit v1.2.3 From dc53ca89f685155ff00103ed013b1ed6a6ad91a6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:18:22 -0800 Subject: X86: Add a flag to force memory accesses to happen at CPL 0. --- src/arch/x86/insts/microldstop.hh | 12 ++++- src/arch/x86/isa/includes.isa | 1 + src/arch/x86/isa/microops/ldstop.isa | 86 +++++++++++++++++++++--------------- src/arch/x86/tlb.cc | 3 +- 4 files changed, 64 insertions(+), 38 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/insts/microldstop.hh b/src/arch/x86/insts/microldstop.hh index eccd37dc2..f0051e2cf 100644 --- a/src/arch/x86/insts/microldstop.hh +++ b/src/arch/x86/insts/microldstop.hh @@ -60,9 +60,16 @@ #include "arch/x86/insts/microop.hh" #include "mem/packet.hh" +#include "mem/request.hh" namespace X86ISA { + static const Request::FlagsType SegmentFlagMask = mask(4); + static const int FlagShift = 4; + enum FlagBit { + CPL0FlagBit = 1 + }; + /** * Base class for load and store ops */ @@ -77,6 +84,7 @@ namespace X86ISA const RegIndex data; const uint8_t dataSize; const uint8_t addressSize; + const Request::FlagsType memFlags; RegIndex foldOBit, foldABit; //Constructor @@ -87,13 +95,15 @@ namespace X86ISA uint64_t _disp, uint8_t _segment, RegIndex _data, uint8_t _dataSize, uint8_t _addressSize, + Request::FlagsType _memFlags, OpClass __opClass) : X86MicroopBase(machInst, mnem, _instMnem, isMicro, isDelayed, isFirst, isLast, __opClass), scale(_scale), index(_index), base(_base), disp(_disp), segment(_segment), data(_data), - dataSize(_dataSize), addressSize(_addressSize) + dataSize(_dataSize), addressSize(_addressSize), + memFlags(_memFlags | _segment) { foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0; foldABit = diff --git a/src/arch/x86/isa/includes.isa b/src/arch/x86/isa/includes.isa index 909f2f389..10bac86ed 100644 --- a/src/arch/x86/isa/includes.isa +++ b/src/arch/x86/isa/includes.isa @@ -117,6 +117,7 @@ output decoder {{ #include "arch/x86/microcode_rom.hh" #include "arch/x86/miscregs.hh" #include "arch/x86/segmentregs.hh" +#include "arch/x86/tlb.hh" #include "base/cprintf.hh" #include "base/loader/symtab.hh" #include "base/misc.hh" diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index 5697f781b..097b0e311 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -124,14 +124,16 @@ def template MicroLeaDeclare {{ uint8_t _scale, RegIndex _index, RegIndex _base, uint64_t _disp, uint8_t _segment, RegIndex _data, - uint8_t _dataSize, uint8_t _addressSize); + uint8_t _dataSize, uint8_t _addressSize, + Request::FlagsType _memFlags); %(class_name)s(ExtMachInst _machInst, const char * instMnem, uint8_t _scale, RegIndex _index, RegIndex _base, uint64_t _disp, uint8_t _segment, RegIndex _data, - uint8_t _dataSize, uint8_t _addressSize); + uint8_t _dataSize, uint8_t _addressSize, + Request::FlagsType _memFlags); %(BasicExecDeclare)s }; @@ -151,7 +153,7 @@ def template MicroLoadExecute {{ %(ea_code)s; DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); - fault = read(xc, EA, Mem, (%(mem_flags)s) | segment); + fault = read(xc, EA, Mem, memFlags); if(fault == NoFault) { @@ -178,7 +180,7 @@ def template MicroLoadInitiateAcc {{ %(ea_code)s; DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); - fault = read(xc, EA, Mem, (%(mem_flags)s) | segment); + fault = read(xc, EA, Mem, memFlags); return fault; } @@ -225,7 +227,7 @@ def template MicroStoreExecute {{ if(fault == NoFault) { - fault = write(xc, Mem, EA, (%(mem_flags)s) | segment); + fault = write(xc, Mem, EA, memFlags); if(fault == NoFault) { %(post_code)s; @@ -253,7 +255,7 @@ def template MicroStoreInitiateAcc {{ if(fault == NoFault) { - write(xc, Mem, EA, (%(mem_flags)s) | segment); + write(xc, Mem, EA, memFlags); } return fault; } @@ -296,14 +298,16 @@ def template MicroLdStOpDeclare {{ uint8_t _scale, RegIndex _index, RegIndex _base, uint64_t _disp, uint8_t _segment, RegIndex _data, - uint8_t _dataSize, uint8_t _addressSize); + uint8_t _dataSize, uint8_t _addressSize, + Request::FlagsType _memFlags); %(class_name)s(ExtMachInst _machInst, const char * instMnem, uint8_t _scale, RegIndex _index, RegIndex _base, uint64_t _disp, uint8_t _segment, RegIndex _data, - uint8_t _dataSize, uint8_t _addressSize); + uint8_t _dataSize, uint8_t _addressSize, + Request::FlagsType _memFlags); %(BasicExecDeclare)s @@ -325,12 +329,13 @@ def template MicroLdStOpConstructor {{ uint8_t _scale, RegIndex _index, RegIndex _base, uint64_t _disp, uint8_t _segment, RegIndex _data, - uint8_t _dataSize, uint8_t _addressSize) : + uint8_t _dataSize, uint8_t _addressSize, + Request::FlagsType _memFlags) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, false, false, false, false, _scale, _index, _base, _disp, _segment, _data, - _dataSize, _addressSize, %(op_class)s) + _dataSize, _addressSize, _memFlags, %(op_class)s) { buildMe(); } @@ -341,12 +346,13 @@ def template MicroLdStOpConstructor {{ uint8_t _scale, RegIndex _index, RegIndex _base, uint64_t _disp, uint8_t _segment, RegIndex _data, - uint8_t _dataSize, uint8_t _addressSize) : + uint8_t _dataSize, uint8_t _addressSize, + Request::FlagsType _memFlags) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, isMicro, isDelayed, isFirst, isLast, _scale, _index, _base, _disp, _segment, _data, - _dataSize, _addressSize, %(op_class)s) + _dataSize, _addressSize, _memFlags, %(op_class)s) { buildMe(); } @@ -354,26 +360,31 @@ def template MicroLdStOpConstructor {{ let {{ class LdStOp(X86Microop): - def __init__(self, data, segment, addr, disp, dataSize, addressSize): + def __init__(self, data, segment, addr, disp, + dataSize, addressSize, baseFlags, atCPL0): self.data = data [self.scale, self.index, self.base] = addr self.disp = disp self.segment = segment self.dataSize = dataSize self.addressSize = addressSize + self.memFlags = baseFlags + if atCPL0: + self.memFlags += " | (CPL0FlagBit << FlagShift)" def getAllocator(self, *microFlags): allocator = '''new %(class_name)s(machInst, macrocodeBlock %(flags)s, %(scale)s, %(index)s, %(base)s, %(disp)s, %(segment)s, %(data)s, - %(dataSize)s, %(addressSize)s)''' % { + %(dataSize)s, %(addressSize)s, %(memFlags)s)''' % { "class_name" : self.className, "flags" : self.microFlagsText(microFlags), "scale" : self.scale, "index" : self.index, "base" : self.base, "disp" : self.disp, "segment" : self.segment, "data" : self.data, - "dataSize" : self.dataSize, "addressSize" : self.addressSize} + "dataSize" : self.dataSize, "addressSize" : self.addressSize, + "memFlags" : self.memFlags} return allocator }}; @@ -387,7 +398,7 @@ let {{ calculateEA = "EA = SegBase + scale * Index + Base + disp;" - def defineMicroLoadOp(mnemonic, code, mem_flags=0): + def defineMicroLoadOp(mnemonic, code, mem_flags="0"): global header_output global decoder_output global exec_output @@ -398,8 +409,7 @@ let {{ # Build up the all register version of this micro op iop = InstObjParams(name, Name, 'X86ISA::LdStOp', {"code": code, - "ea_code": calculateEA, - "mem_flags": mem_flags}) + "ea_code": calculateEA}) header_output += MicroLdStOpDeclare.subst(iop) decoder_output += MicroLdStOpConstructor.subst(iop) exec_output += MicroLoadExecute.subst(iop) @@ -408,16 +418,19 @@ let {{ class LoadOp(LdStOp): def __init__(self, data, segment, addr, disp = 0, - dataSize="env.dataSize", addressSize="env.addressSize"): - super(LoadOp, self).__init__(data, segment, - addr, disp, dataSize, addressSize) + dataSize="env.dataSize", + addressSize="env.addressSize", + atCPL0=False): + super(LoadOp, self).__init__(data, segment, addr, + disp, dataSize, addressSize, mem_flags, atCPL0) self.className = Name self.mnemonic = name microopClasses[name] = LoadOp defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);') - defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);', 'StoreCheck') + defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);', + 'X86ISA::StoreCheck') defineMicroLoadOp('Ldfp', 'FpData.uqw = Mem;') def defineMicroStoreOp(mnemonic, code, \ @@ -434,8 +447,7 @@ let {{ {"code": code, "post_code": postCode, "complete_code": completeCode, - "ea_code": calculateEA, - "mem_flags": mem_flags}) + "ea_code": calculateEA}) header_output += MicroLdStOpDeclare.subst(iop) decoder_output += MicroLdStOpConstructor.subst(iop) exec_output += MicroStoreExecute.subst(iop) @@ -444,9 +456,11 @@ let {{ class StoreOp(LdStOp): def __init__(self, data, segment, addr, disp = 0, - dataSize="env.dataSize", addressSize="env.addressSize"): - super(StoreOp, self).__init__(data, segment, - addr, disp, dataSize, addressSize) + dataSize="env.dataSize", + addressSize="env.addressSize", + atCPL0=False): + super(StoreOp, self).__init__(data, segment, addr, + disp, dataSize, addressSize, mem_flags, atCPL0) self.className = Name self.mnemonic = name @@ -461,8 +475,7 @@ let {{ iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp', {"code": "Data = merge(Data, EA, dataSize);", - "ea_code": calculateEA, - "mem_flags": 0}) + "ea_code": calculateEA}) header_output += MicroLeaDeclare.subst(iop) decoder_output += MicroLdStOpConstructor.subst(iop) exec_output += MicroLeaExecute.subst(iop) @@ -471,7 +484,7 @@ let {{ def __init__(self, data, segment, addr, disp = 0, dataSize="env.dataSize", addressSize="env.addressSize"): super(LeaOp, self).__init__(data, segment, - addr, disp, dataSize, addressSize) + addr, disp, dataSize, addressSize, "0", False) self.className = "Lea" self.mnemonic = "lea" @@ -480,17 +493,17 @@ let {{ iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp', {"code": "xc->demapPage(EA, 0);", - "ea_code": calculateEA, - "mem_flags": 0}) + "ea_code": calculateEA}) header_output += MicroLeaDeclare.subst(iop) decoder_output += MicroLdStOpConstructor.subst(iop) exec_output += MicroLeaExecute.subst(iop) class TiaOp(LdStOp): def __init__(self, segment, addr, disp = 0, - dataSize="env.dataSize", addressSize="env.addressSize"): + dataSize="env.dataSize", + addressSize="env.addressSize"): super(TiaOp, self).__init__("NUM_INTREGS", segment, - addr, disp, dataSize, addressSize) + addr, disp, dataSize, addressSize, "0", False) self.className = "Tia" self.mnemonic = "tia" @@ -498,9 +511,10 @@ let {{ class CdaOp(LdStOp): def __init__(self, segment, addr, disp = 0, - dataSize="env.dataSize", addressSize="env.addressSize"): + dataSize="env.dataSize", + addressSize="env.addressSize", atCPL0=False): super(CdaOp, self).__init__("NUM_INTREGS", segment, - addr, disp, dataSize, addressSize) + addr, disp, dataSize, addressSize, "0", atCPL0) self.className = "Cda" self.mnemonic = "cda" diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 3962cd607..372c8b997 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -59,6 +59,7 @@ #include "config/full_system.hh" +#include "arch/x86/insts/microldstop.hh" #include "arch/x86/pagetable.hh" #include "arch/x86/tlb.hh" #include "arch/x86/x86_traits.hh" @@ -195,7 +196,7 @@ TLB::translate(RequestPtr req, ThreadContext *tc, uint32_t flags = req->getFlags(); bool storeCheck = flags & StoreCheck; - int seg = flags & mask(4); + int seg = flags & SegmentFlagMask; //XXX Junk code to surpress the warning if (storeCheck); -- cgit v1.2.3 From ba6918463049c5a60d4375348c99e46d9901d1e8 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:18:29 -0800 Subject: X86: Use atCPL0 for accesses that are part of CPU machinery. --- src/arch/x86/isa/insts/romutil.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/romutil.py b/src/arch/x86/isa/insts/romutil.py index 93276addc..beeda3d12 100644 --- a/src/arch/x86/isa/insts/romutil.py +++ b/src/arch/x86/isa/insts/romutil.py @@ -40,8 +40,8 @@ def rom # Load the gate descriptor from the IDT slli t4, t1, 4, dataSize=8 - ld t2, idtr, [1, t0, t4], 8, dataSize=8, addressSize=8 - ld t4, idtr, [1, t0, t4], dataSize=8, addressSize=8 + ld t2, idtr, [1, t0, t4], 8, dataSize=8, addressSize=8, atCPL0=True + ld t4, idtr, [1, t0, t4], dataSize=8, addressSize=8, atCPL0=True # Make sure the descriptor is a legal gate. chks t1, t4, %(gateCheckType)s @@ -54,10 +54,10 @@ def rom andi t5, t10, 0xF8, dataSize=8 andi t0, t10, 0x4, flags=(EZF,), dataSize=2 br rom_local_label("%(startLabel)s_globalDescriptor"), flags=(CEZF,) - ld t3, tsl, [1, t0, t5], dataSize=8, addressSize=8 + ld t3, tsl, [1, t0, t5], dataSize=8, addressSize=8, atCPL0=True br rom_local_label("%(startLabel)s_processDescriptor") %(startLabel)s_globalDescriptor: - ld t3, tsg, [1, t0, t5], dataSize=8, addressSize=8 + ld t3, tsg, [1, t0, t5], dataSize=8, addressSize=8, atCPL0=True %(startLabel)s_processDescriptor: chks t10, t3, IntCSCheck, dataSize=8 wrdl hs, t3, t10, dataSize=8 @@ -104,18 +104,13 @@ def rom %(startLabel)s_cplStackSwitch: # Get the new rsp from the TSS - ld t6, tr, [8, t10, t0], 4, dataSize=8, addressSize=8 + ld t6, tr, [8, t10, t0], 4, dataSize=8, addressSize=8, atCPL0=True %(startLabel)s_stackSwitched: andi t6, t6, 0xF0, dataSize=1 subi t6, t6, 40 + %(errorCodeSize)d, dataSize=8 - # Check that we can access everything we need to on the stack - ldst t0, hs, [1, t0, t6], dataSize=8, addressSize=8 - ldst t0, hs, [1, t0, t6], \ - 32 + %(errorCodeSize)d, dataSize=8, addressSize=8 - ## ## Point of no return. ## We're now going to irrevocably modify visible state. @@ -136,6 +131,11 @@ def rom rdsel t10, cs, dataSize=2 wrsel cs, t5, dataSize=2 + # Check that we can access everything we need to on the stack + ldst t0, hs, [1, t0, t6], dataSize=8, addressSize=8 + ldst t0, hs, [1, t0, t6], \ + 32 + %(errorCodeSize)d, dataSize=8, addressSize=8 + # # Build up the interrupt stack frame -- cgit v1.2.3 From f35a37ca9eb7ff25c0da5ec14b83f77f5321222c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:18:51 -0800 Subject: X86: Update CS later so stack accesses have the right permission checks. --- .../control_transfer/interrupts_and_exceptions.py | 31 +++++++++++----------- 1 file changed, 15 insertions(+), 16 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py index 1f14eb95c..8d66cc445 100644 --- a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py +++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py @@ -118,20 +118,13 @@ protToVirtFallThrough: andi t6, t2, 0xF8, dataSize=8 andi t0, t2, 0x4, flags=(EZF,), dataSize=2 br label("globalCSDescriptor"), flags=(CEZF,) - ld t6, tsl, [1, t0, t6], dataSize=8 + ld t8, tsl, [1, t0, t6], dataSize=8 br label("processCSDescriptor") globalCSDescriptor: - ld t6, tsg, [1, t0, t6], dataSize=8 + ld t8, tsg, [1, t0, t6], dataSize=8 processCSDescriptor: chks t2, t6, dataSize=8 - # This actually updates state which is wrong. It should wait until we know - # we're not going to fault. Unfortunately, that's hard to do. - wrdl cs, t6, t2 - wrsel cs, t2 - - #CPL = temp_CPL - ### ### Get the new stack pointer and stack segment off the old stack if necessary, @@ -175,24 +168,24 @@ doPopStackStuff: # POP.v temp_RSP ld t6, ss, [1, t0, rsp], "3 * env.dataSize", dataSize=ssz # POP.v temp_SS - ld t2, ss, [1, t0, rsp], "4 * env.dataSize", dataSize=ssz + ld t9, ss, [1, t0, rsp], "4 * env.dataSize", dataSize=ssz # SS = READ_DESCRIPTOR (temp_SS, ss_chk) - andi t0, t2, 0xFC, flags=(EZF,), dataSize=2 + andi t0, t9, 0xFC, flags=(EZF,), dataSize=2 br label("processSSDescriptor"), flags=(CEZF,) - andi t7, t2, 0xF8, dataSize=8 - andi t0, t2, 0x4, flags=(EZF,), dataSize=2 + andi t7, t9, 0xF8, dataSize=8 + andi t0, t9, 0x4, flags=(EZF,), dataSize=2 br label("globalSSDescriptor"), flags=(CEZF,) ld t7, tsl, [1, t0, t7], dataSize=8 br label("processSSDescriptor") globalSSDescriptor: ld t7, tsg, [1, t0, t7], dataSize=8 processSSDescriptor: - chks t2, t7, dataSize=8 + chks t9, t7, dataSize=8 # This actually updates state which is wrong. It should wait until we know # we're not going to fault. Unfortunately, that's hard to do. - wrdl ss, t7, t2 - wrsel ss, t2 + wrdl ss, t7, t9 + wrsel ss, t9 ### ### From this point downwards, we can't fault. We can update user visible state. @@ -204,6 +197,12 @@ processSSDescriptor: fallThroughPopStackStuff: + # Update CS + wrdl cs, t8, t2 + wrsel cs, t2 + + #CPL = temp_CPL + #IF (changing CPL) #{ srli t7, t4, 4 -- cgit v1.2.3 From c849ef58c05e00e8523d6f2a9d8f0da6315e75d9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:18:58 -0800 Subject: X86: Actually check page protections. --- src/arch/x86/tlb.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 372c8b997..603d4e45f 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -649,6 +649,18 @@ TLB::translate(RequestPtr req, ThreadContext *tc, #endif } // Do paging protection checks. + bool inUser = (csAttr.dpl == 3 && + !(flags & (CPL0FlagBit << FlagShift))); + if (inUser && !entry->user || + write && !entry->writable) { + // The page must have been present to get into the TLB in + // the first place. We'll assume the reserved bits are + // fine even though we're not checking them. + return new PageFault(vaddr, true, write, + inUser, false, execute); + } + + DPRINTF(TLB, "Entry found with paddr %#x, " "doing protection checks.\n", entry->paddr); Addr paddr = entry->paddr | (vaddr & (entry->size-1)); -- cgit v1.2.3 From 5f0428ef9fc7acc5b1315f6c87202c1ee13f0b8b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:19:14 -0800 Subject: X86: Use the right portion of a register for stores. --- src/arch/x86/isa/microops/ldstop.isa | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index 097b0e311..a1aaddfe2 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -466,9 +466,9 @@ let {{ microopClasses[name] = StoreOp - defineMicroStoreOp('St', 'Mem = Data;') + defineMicroStoreOp('St', 'Mem = pick(Data, 2, dataSize);') defineMicroStoreOp('Stfp', 'Mem = FpData.uqw;') - defineMicroStoreOp('Stupd', 'Mem = Data;', + defineMicroStoreOp('Stupd', 'Mem = pick(Data, 2, dataSize);', 'Base = merge(Base, EA - SegBase, addressSize);', 'Base = merge(Base, pkt->req->getVaddr() - SegBase, addressSize);'); defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS") -- cgit v1.2.3 From 06ff83e1b9aa2a00af4f66fae7c9fce2ac36394a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:19:22 -0800 Subject: X86: Implement a basic prefetch instruction. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 4 ++-- src/arch/x86/isa/includes.isa | 1 + .../general_purpose/cache_and_memory_management.py | 28 +++++++++++++++++++--- src/arch/x86/isa/microops/ldstop.isa | 23 +++++++++++------- 4 files changed, 42 insertions(+), 14 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index fa49c55d3..a0a08df8f 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -281,7 +281,7 @@ 0x2: Inst::UD2(); 0x3: Inst::UD2(); 0x4: Inst::UD2(); - 0x5: prefetch(); + 0x5: Inst::PREFETCH(Mb); 0x6: FailUnimpl::femms(); 0x7: FailUnimpl::threednow(); } @@ -335,7 +335,7 @@ //group17(); 0x0: decode MODRM_REG { 0x0: prefetch_nta(); - 0x1: prefetch_t0(); + 0x1: Inst::PREFETCH_T0(Mb); 0x2: prefetch_t1(); 0x3: prefetch_t2(); default: Inst::HINT_NOP(); diff --git a/src/arch/x86/isa/includes.isa b/src/arch/x86/isa/includes.isa index 10bac86ed..8626f117a 100644 --- a/src/arch/x86/isa/includes.isa +++ b/src/arch/x86/isa/includes.isa @@ -157,6 +157,7 @@ output exec {{ #include "sim/sim_exit.hh" #include "mem/packet.hh" #include "mem/packet_access.hh" +#include "mem/request.hh" #include "sim/pseudo_inst.hh" using namespace X86ISA; diff --git a/src/arch/x86/isa/insts/general_purpose/cache_and_memory_management.py b/src/arch/x86/isa/insts/general_purpose/cache_and_memory_management.py index 08b842825..dbd2d8b84 100644 --- a/src/arch/x86/isa/insts/general_purpose/cache_and_memory_management.py +++ b/src/arch/x86/isa/insts/general_purpose/cache_and_memory_management.py @@ -53,7 +53,31 @@ # # Authors: Gabe Black -microcode = "" +microcode = ''' +def macroop PREFETCH_M +{ + ld t0, seg, sib, disp, dataSize=1, prefetch=True +}; + +def macroop PREFETCH_P +{ + rdip t7 + ld t0, seg, riprel, disp, dataSize=1, prefetch=True +}; + +def macroop PREFETCH_T0_M +{ + ld t0, seg, sib, disp, dataSize=1, prefetch=True +}; + +def macroop PREFETCH_T0_P +{ + rdip t7 + ld t0, seg, riprel, disp, dataSize=1, prefetch=True +}; + +''' + #let {{ # class LFENCE(Inst): # "GenFault ${new UnimpInstFault}" @@ -63,8 +87,6 @@ microcode = "" # "GenFault ${new UnimpInstFault}" # class PREFETCHlevel(Inst): # "GenFault ${new UnimpInstFault}" -# class PREFETCH(Inst): -# "GenFault ${new UnimpInstFault}" # class PREFETCHW(Inst): # "GenFault ${new UnimpInstFault}" # class CLFLUSH(Inst): diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index a1aaddfe2..3bc238174 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -155,9 +155,11 @@ def template MicroLoadExecute {{ fault = read(xc, EA, Mem, memFlags); - if(fault == NoFault) - { + if (fault == NoFault) { %(code)s; + } else if (memFlags & Request::PF_EXCLUSIVE) { + // For prefetches, ignore any faults/exceptions. + return NoFault; } if(fault == NoFault) { @@ -361,7 +363,7 @@ def template MicroLdStOpConstructor {{ let {{ class LdStOp(X86Microop): def __init__(self, data, segment, addr, disp, - dataSize, addressSize, baseFlags, atCPL0): + dataSize, addressSize, baseFlags, atCPL0, prefetch): self.data = data [self.scale, self.index, self.base] = addr self.disp = disp @@ -371,6 +373,8 @@ let {{ self.memFlags = baseFlags if atCPL0: self.memFlags += " | (CPL0FlagBit << FlagShift)" + if prefetch: + self.memFlags += " | Request::PF_EXCLUSIVE" def getAllocator(self, *microFlags): allocator = '''new %(class_name)s(machInst, macrocodeBlock @@ -420,9 +424,10 @@ let {{ def __init__(self, data, segment, addr, disp = 0, dataSize="env.dataSize", addressSize="env.addressSize", - atCPL0=False): + atCPL0=False, prefetch=False): super(LoadOp, self).__init__(data, segment, addr, - disp, dataSize, addressSize, mem_flags, atCPL0) + disp, dataSize, addressSize, mem_flags, + atCPL0, prefetch) self.className = Name self.mnemonic = name @@ -460,7 +465,7 @@ let {{ addressSize="env.addressSize", atCPL0=False): super(StoreOp, self).__init__(data, segment, addr, - disp, dataSize, addressSize, mem_flags, atCPL0) + disp, dataSize, addressSize, mem_flags, atCPL0, False) self.className = Name self.mnemonic = name @@ -484,7 +489,7 @@ let {{ def __init__(self, data, segment, addr, disp = 0, dataSize="env.dataSize", addressSize="env.addressSize"): super(LeaOp, self).__init__(data, segment, - addr, disp, dataSize, addressSize, "0", False) + addr, disp, dataSize, addressSize, "0", False, False) self.className = "Lea" self.mnemonic = "lea" @@ -503,7 +508,7 @@ let {{ dataSize="env.dataSize", addressSize="env.addressSize"): super(TiaOp, self).__init__("NUM_INTREGS", segment, - addr, disp, dataSize, addressSize, "0", False) + addr, disp, dataSize, addressSize, "0", False, False) self.className = "Tia" self.mnemonic = "tia" @@ -514,7 +519,7 @@ let {{ dataSize="env.dataSize", addressSize="env.addressSize", atCPL0=False): super(CdaOp, self).__init__("NUM_INTREGS", segment, - addr, disp, dataSize, addressSize, "0", atCPL0) + addr, disp, dataSize, addressSize, "0", atCPL0, False) self.className = "Cda" self.mnemonic = "cda" -- cgit v1.2.3 From d48214a6560049643f39873a533f27d5c8895a4e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:19:41 -0800 Subject: X86: Implement the fence instructions. These are not microcoded. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index a0a08df8f..edacf5bcb 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -831,9 +831,12 @@ //0x6: group16(); 0x6: decode MODRM_MOD { 0x3: decode MODRM_REG { - 0x5: lfence(); - 0x6: mfence(); - 0x7: sfence(); + 0x5: BasicOperate::LFENCE( + {{/*Nothing*/}}, IsReadBarrier); + 0x6: BasicOperate::MFENCE( + {{/*Nothing*/}}, IsMemBarrier); + 0x7: BasicOperate::SFENCE( + {{/*Nothing*/}}, IsWriteBarrier); default: Inst::UD2(); } default: decode MODRM_REG { -- cgit v1.2.3 From cb4141f6e679db9725ad152df89941998535ad95 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:19:47 -0800 Subject: X86: Check src1 for illegal values since that's the index we actually use. --- src/arch/x86/isa/microops/regop.isa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 4434f9e74..74c93a20a 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -928,7 +928,7 @@ let {{ super(Rdcr, self).__init__(dest, \ src1, "NUM_INTREGS", flags, dataSize) code = ''' - if (dest == 1 || (dest > 4 && dest < 8) || (dest > 8)) { + if (src1 == 1 || (src1 > 4 && src1 < 8) || (src1 > 8)) { fault = new InvalidOpcode(); } else { DestReg = ControlSrc1; -- cgit v1.2.3 From 11fbed02ea88f72d61f16922ff17ceb8221bef6b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:19:54 -0800 Subject: X86: Add classes that break out the bits of the DR6 and DR7 registers. --- src/arch/x86/miscregs.hh | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/miscregs.hh b/src/arch/x86/miscregs.hh index a536d9e3b..af02e9422 100644 --- a/src/arch/x86/miscregs.hh +++ b/src/arch/x86/miscregs.hh @@ -572,6 +572,38 @@ namespace X86ISA Bitfield<3, 0> tpr; // Task Priority Register EndBitUnion(CR8) + BitUnion64(DR6) + Bitfield<0> b0; + Bitfield<1> b1; + Bitfield<2> b2; + Bitfield<3> b3; + Bitfield<13> bd; + Bitfield<14> bs; + Bitfield<15> bt; + EndBitUnion(DR6) + + BitUnion64(DR7) + Bitfield<0> l0; + Bitfield<1> g0; + Bitfield<2> l1; + Bitfield<3> g1; + Bitfield<4> l2; + Bitfield<5> g2; + Bitfield<6> l3; + Bitfield<7> g3; + Bitfield<8> le; + Bitfield<9> ge; + Bitfield<13> gd; + Bitfield<17, 16> rw0; + Bitfield<19, 18> len0; + Bitfield<21, 20> rw1; + Bitfield<23, 22> len1; + Bitfield<25, 24> rw2; + Bitfield<27, 26> len2; + Bitfield<29, 28> rw3; + Bitfield<31, 30> len3; + EndBitUnion(DR7) + // MTRR capabilities BitUnion64(MTRRcap) Bitfield<7, 0> vcnt; // Variable-Range Register Count -- cgit v1.2.3 From 28a35a6adbe083bbe7ff34dfe29d57a408f18bdb Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:20:01 -0800 Subject: X86: Add microops for reading/writing debug registers. --- src/arch/x86/isa/microops/regop.isa | 36 ++++++++++++++++++++++++++++++++ src/arch/x86/isa/operands.isa | 41 ++++++++++++++++++++----------------- 2 files changed, 58 insertions(+), 19 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 74c93a20a..ceecfbf1c 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -923,6 +923,42 @@ let {{ class Zext(RegOp): code = 'DestReg = bits(psrc1, op2, 0);' + class Rddr(RegOp): + def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): + super(Rddr, self).__init__(dest, \ + src1, "NUM_INTREGS", flags, dataSize) + code = ''' + CR4 cr4 = CR4Op; + DR7 dr7 = DR7Op; + if ((cr4.de == 1 && (src1 == 4 || src1 == 5)) || src1 >= 8) { + fault = new InvalidOpcode(); + } else if (dr7.gd) { + fault = new DebugException(); + } else { + DestReg = merge(DestReg, DebugSrc1, dataSize); + } + ''' + + class Wrdr(RegOp): + def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): + super(Wrdr, self).__init__(dest, \ + src1, "NUM_INTREGS", flags, dataSize) + code = ''' + CR4 cr4 = CR4Op; + DR7 dr7 = DR7Op; + if ((cr4.de == 1 && (dest == 4 || dest == 5)) || dest >= 8) { + fault = new InvalidOpcode(); + } else if ((dest == 6 || dest == 7) && + bits(psrc1, 63, 32) && + machInst.mode.mode == LongMode) { + fault = new GeneralProtection(0); + } else if (dr7.gd) { + fault = new DebugException(); + } else { + DebugDest = psrc1; + } + ''' + class Rdcr(RegOp): def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): super(Rdcr, self).__init__(dest, \ diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index d46741f00..ab1e9a851 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -138,28 +138,31 @@ def operands {{ # original instruction. 'ControlDest': ('ControlReg', 'uqw', 'MISCREG_CR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 100), 'ControlSrc1': ('ControlReg', 'uqw', 'MISCREG_CR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 101), - 'SegBaseDest': ('ControlReg', 'uqw', 'MISCREG_SEG_BASE(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 102), - 'SegBaseSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_BASE(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 103), - 'SegLimitDest': ('ControlReg', 'uqw', 'MISCREG_SEG_LIMIT(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 104), - 'SegLimitSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_LIMIT(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 105), - 'SegSelDest': ('ControlReg', 'uqw', 'MISCREG_SEG_SEL(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 106), - 'SegSelSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_SEL(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 107), - 'SegAttrDest': ('ControlReg', 'uqw', 'MISCREG_SEG_ATTR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 108), - 'SegAttrSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_ATTR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 109), + 'DebugDest': ('ControlReg', 'uqw', 'MISCREG_DR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 102), + 'DebugSrc1': ('ControlReg', 'uqw', 'MISCREG_DR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 103), + 'SegBaseDest': ('ControlReg', 'uqw', 'MISCREG_SEG_BASE(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 104), + 'SegBaseSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_BASE(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 105), + 'SegLimitDest': ('ControlReg', 'uqw', 'MISCREG_SEG_LIMIT(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 106), + 'SegLimitSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_LIMIT(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 107), + 'SegSelDest': ('ControlReg', 'uqw', 'MISCREG_SEG_SEL(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 108), + 'SegSelSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_SEL(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 109), + 'SegAttrDest': ('ControlReg', 'uqw', 'MISCREG_SEG_ATTR(dest)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 110), + 'SegAttrSrc1': ('ControlReg', 'uqw', 'MISCREG_SEG_ATTR(src1)', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 111), # Operands to access specific control registers directly. 'EferOp': ('ControlReg', 'uqw', 'MISCREG_EFER', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 200), 'CR4Op': ('ControlReg', 'uqw', 'MISCREG_CR4', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 201), - 'LDTRBase': ('ControlReg', 'uqw', 'MISCREG_TSL_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 202), - 'LDTRLimit': ('ControlReg', 'uqw', 'MISCREG_TSL_LIMIT', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 203), - 'LDTRSel': ('ControlReg', 'uqw', 'MISCREG_TSL', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 204), - 'GDTRBase': ('ControlReg', 'uqw', 'MISCREG_TSG_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 205), - 'GDTRLimit': ('ControlReg', 'uqw', 'MISCREG_TSG_LIMIT', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 206), - 'CSBase': ('ControlReg', 'udw', 'MISCREG_CS_EFF_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 207), - 'CSAttr': ('ControlReg', 'udw', 'MISCREG_CS_ATTR', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 208), - 'MiscRegDest': ('ControlReg', 'uqw', 'dest', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 209), - 'MiscRegSrc1': ('ControlReg', 'uqw', 'src1', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 210), - 'TscOp': ('ControlReg', 'uqw', 'MISCREG_TSC', (None, None, ['IsSerializeAfter', 'IsSerializing', 'IsNonSpeculative']), 211), - 'M5Reg': ('ControlReg', 'uqw', 'MISCREG_M5_REG', (None, None, None), 212), + 'DR7Op': ('ControlReg', 'uqw', 'MISCREG_DR7', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 202), + 'LDTRBase': ('ControlReg', 'uqw', 'MISCREG_TSL_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 203), + 'LDTRLimit': ('ControlReg', 'uqw', 'MISCREG_TSL_LIMIT', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 204), + 'LDTRSel': ('ControlReg', 'uqw', 'MISCREG_TSL', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 205), + 'GDTRBase': ('ControlReg', 'uqw', 'MISCREG_TSG_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 206), + 'GDTRLimit': ('ControlReg', 'uqw', 'MISCREG_TSG_LIMIT', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 207), + 'CSBase': ('ControlReg', 'udw', 'MISCREG_CS_EFF_BASE', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 208), + 'CSAttr': ('ControlReg', 'udw', 'MISCREG_CS_ATTR', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 209), + 'MiscRegDest': ('ControlReg', 'uqw', 'dest', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 210), + 'MiscRegSrc1': ('ControlReg', 'uqw', 'src1', (None, None, ['IsSerializeAfter','IsSerializing','IsNonSpeculative']), 211), + 'TscOp': ('ControlReg', 'uqw', 'MISCREG_TSC', (None, None, ['IsSerializeAfter', 'IsSerializing', 'IsNonSpeculative']), 212), + 'M5Reg': ('ControlReg', 'uqw', 'MISCREG_M5_REG', (None, None, None), 213), 'Mem': ('Mem', 'uqw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 300) }}; -- cgit v1.2.3 From 8813168b5a3830b0b0a65b0342aca7b607e74b42 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:20:10 -0800 Subject: X86: Do a merge for the zero extension microop. --- .../x86/isa/insts/general_purpose/data_conversion/translate.py | 2 +- src/arch/x86/isa/insts/general_purpose/data_transfer/move.py | 6 +++--- .../isa/insts/general_purpose/data_transfer/stack_operations.py | 4 ++-- src/arch/x86/isa/insts/general_purpose/input_output/general_io.py | 4 ++-- src/arch/x86/isa/insts/general_purpose/input_output/string_io.py | 8 ++++---- src/arch/x86/isa/insts/system/segmentation.py | 8 ++++---- src/arch/x86/isa/microops/regop.isa | 2 +- 7 files changed, 17 insertions(+), 17 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/data_conversion/translate.py b/src/arch/x86/isa/insts/general_purpose/data_conversion/translate.py index d6ae7885a..c334693e5 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_conversion/translate.py +++ b/src/arch/x86/isa/insts/general_purpose/data_conversion/translate.py @@ -55,7 +55,7 @@ microcode = ''' def macroop XLAT { - zexti t1, rax, 7 + zexti t1, rax, 7, dataSize=8 # Here, t1 can be used directly. The value of al is supposed to be treated # as unsigned. Since we zero extended it from 8 bits above and the address # size has to be at least 16 bits, t1 will not be sign extended. diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py index 1e2c0c42f..0e3e9f270 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py @@ -215,7 +215,7 @@ def macroop MOV_P_S { }; def macroop MOV_REAL_S_R { - zext t2, regm, 15 + zext t2, regm, 15, dataSize=8 slli t3, t2, 2, dataSize=8 wrsel reg, regm wrbase reg, t3 @@ -223,7 +223,7 @@ def macroop MOV_REAL_S_R { def macroop MOV_REAL_S_M { ld t1, seg, sib, disp, dataSize=2 - zext t2, t1, 15 + zext t2, t1, 15, dataSize=8 slli t3, t2, 2, dataSize=8 wrsel reg, t1 wrbase reg, t3 @@ -232,7 +232,7 @@ def macroop MOV_REAL_S_M { def macroop MOV_REAL_S_P { rdip t7 ld t1, seg, riprel, disp, dataSize=2 - zext t2, t1, 15 + zext t2, t1, 15, dataSize=8 slli t3, t2, 2, dataSize=8 wrsel reg, t1 wrbase reg, t3 diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py index 8ec957d11..82fdffc63 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/stack_operations.py @@ -162,9 +162,9 @@ def macroop ENTER_I_I { # Pull the different components out of the immediate limm t1, imm - zexti t2, t1, 15, dataSize=2 + zexti t2, t1, 15, dataSize=8 srl t1, t1, 16 - zexti t1, t1, 5 + zexti t1, t1, 5, dataSize=8 # t1 is now the masked nesting level, and t2 is the amount of storage. # Push rbp. diff --git a/src/arch/x86/isa/insts/general_purpose/input_output/general_io.py b/src/arch/x86/isa/insts/general_purpose/input_output/general_io.py index aba318d73..924bfcb6e 100644 --- a/src/arch/x86/isa/insts/general_purpose/input_output/general_io.py +++ b/src/arch/x86/isa/insts/general_purpose/input_output/general_io.py @@ -89,7 +89,7 @@ microcode = ''' }; def macroop IN_R_R { - zexti t2, regm, 15, dataSize=2 + zexti t2, regm, 15, dataSize=8 ld reg, intseg, [1, t2, t0], "IntAddrPrefixIO << 3", addressSize=4 }; @@ -100,7 +100,7 @@ microcode = ''' }; def macroop OUT_R_R { - zexti t2, reg, 15, dataSize=2 + zexti t2, reg, 15, dataSize=8 st regm, intseg, [1, t2, t0], "IntAddrPrefixIO << 3", addressSize=4 }; ''' diff --git a/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py b/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py index 9d1d4e724..b3bc5ab67 100644 --- a/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py +++ b/src/arch/x86/isa/insts/general_purpose/input_output/string_io.py @@ -61,7 +61,7 @@ def macroop INS_M_R { subi t4, t0, dsz, dataSize=asz mov t3, t3, t4, flags=(nCEZF,), dataSize=asz - zexti t2, reg, 15, dataSize=2 + zexti t2, reg, 15, dataSize=8 ld t6, intseg, [1, t2, t0], "IntAddrPrefixIO << 3", addressSize=8 st t6, es, [1, t0, rdi] @@ -78,7 +78,7 @@ def macroop INS_E_M_R { subi t4, t0, dsz, dataSize=asz mov t3, t3, t4, flags=(nCEZF,), dataSize=asz - zexti t2, reg, 15, dataSize=2 + zexti t2, reg, 15, dataSize=8 topOfLoop: ld t6, intseg, [1, t2, t0], "IntAddrPrefixIO << 3", addressSize=8 @@ -98,7 +98,7 @@ def macroop OUTS_R_M { subi t4, t0, dsz, dataSize=asz mov t3, t3, t4, flags=(nCEZF,), dataSize=asz - zexti t2, reg, 15, dataSize=2 + zexti t2, reg, 15, dataSize=8 ld t6, ds, [1, t0, rsi] st t6, intseg, [1, t2, t0], "IntAddrPrefixIO << 3", addressSize=8 @@ -115,7 +115,7 @@ def macroop OUTS_E_R_M { subi t4, t0, dsz, dataSize=asz mov t3, t3, t4, flags=(nCEZF,), dataSize=asz - zexti t2, reg, 15, dataSize=2 + zexti t2, reg, 15, dataSize=8 topOfLoop: ld t6, ds, [1, t0, rsi] diff --git a/src/arch/x86/isa/insts/system/segmentation.py b/src/arch/x86/isa/insts/system/segmentation.py index c2bb46b7c..2de79f935 100644 --- a/src/arch/x86/isa/insts/system/segmentation.py +++ b/src/arch/x86/isa/insts/system/segmentation.py @@ -92,7 +92,7 @@ def macroop LGDT_16_M ld t1, seg, sib, disp, dataSize=2 # Get the base ld t2, seg, sib, 'adjustedDisp + 2', dataSize=4 - zexti t2, t2, 23 + zexti t2, t2, 23, dataSize=8 wrbase tsg, t2 wrlimit tsg, t1 }; @@ -106,7 +106,7 @@ def macroop LGDT_16_P ld t1, seg, riprel, disp, dataSize=2 # Get the base ld t2, seg, riprel, 'adjustedDisp + 2', dataSize=4 - zexti t2, t2, 23 + zexti t2, t2, 23, dataSize=8 wrbase tsg, t2 wrlimit tsg, t1 }; @@ -149,7 +149,7 @@ def macroop LIDT_16_M ld t1, seg, sib, disp, dataSize=2 # Get the base ld t2, seg, sib, 'adjustedDisp + 2', dataSize=4 - zexti t2, t2, 23 + zexti t2, t2, 23, dataSize=8 wrbase idtr, t2 wrlimit idtr, t1 }; @@ -163,7 +163,7 @@ def macroop LIDT_16_P ld t1, seg, riprel, disp, dataSize=2 # Get the base ld t2, seg, riprel, 'adjustedDisp + 2', dataSize=4 - zexti t2, t2, 23 + zexti t2, t2, 23, dataSize=8 wrbase idtr, t2 wrlimit idtr, t1 }; diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index ceecfbf1c..fd2a3a64f 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -921,7 +921,7 @@ let {{ ''' class Zext(RegOp): - code = 'DestReg = bits(psrc1, op2, 0);' + code = 'DestReg = merge(DestReg, bits(psrc1, op2, 0), dataSize);' class Rddr(RegOp): def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): -- cgit v1.2.3 From 1e70401c08c5976b9ef01b95e100625bdbaf5f3d Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:20:19 -0800 Subject: X86: Fix a few bugs with the segment register instructions in real mode. Fix a few instances where the register form of zext was used where zexti was intended. Also get rid of the 64 bit only rip relative addressed version since 64 bit and real mode are mutually exclusive. --- src/arch/x86/isa/insts/general_purpose/data_transfer/move.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py index 0e3e9f270..82c076216 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py @@ -215,7 +215,7 @@ def macroop MOV_P_S { }; def macroop MOV_REAL_S_R { - zext t2, regm, 15, dataSize=8 + zexti t2, regm, 15, dataSize=8 slli t3, t2, 2, dataSize=8 wrsel reg, regm wrbase reg, t3 @@ -223,19 +223,14 @@ def macroop MOV_REAL_S_R { def macroop MOV_REAL_S_M { ld t1, seg, sib, disp, dataSize=2 - zext t2, t1, 15, dataSize=8 + zexti t2, t1, 15, dataSize=8 slli t3, t2, 2, dataSize=8 wrsel reg, t1 wrbase reg, t3 }; def macroop MOV_REAL_S_P { - rdip t7 - ld t1, seg, riprel, disp, dataSize=2 - zext t2, t1, 15, dataSize=8 - slli t3, t2, 2, dataSize=8 - wrsel reg, t1 - wrbase reg, t3 + panic "RIP relative addressing shouldn't happen in real mode" }; def macroop MOV_S_R { -- cgit v1.2.3 From 3ca2451d811ae7dc2e27923e1af575b6b784ceb9 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:20:25 -0800 Subject: X86: Add code to interpret debug register values. --- src/arch/x86/miscregfile.cc | 74 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc index 388a83e8d..01aac14b1 100644 --- a/src/arch/x86/miscregfile.cc +++ b/src/arch/x86/miscregfile.cc @@ -104,8 +104,11 @@ string X86ISA::getMiscRegName(RegIndex index) void MiscRegFile::clear() { - // Blank everything. 0 might not be an appropriate value for some things. + // Blank everything. 0 might not be an appropriate value for some things, + // but it is for most. memset(regVal, 0, NumMiscRegs * sizeof(MiscReg)); + regVal[MISCREG_DR6] = (mask(8) << 4) | (mask(16) << 16); + regVal[MISCREG_DR7] = 1 << 10; } MiscReg MiscRegFile::readRegNoEffect(MiscRegIndex miscReg) @@ -267,6 +270,75 @@ void MiscRegFile::setReg(MiscRegIndex miscReg, case MISCREG_TSC: regVal[MISCREG_TSC] = val - tc->getCpuPtr()->curCycle(); return; + case MISCREG_DR0: + case MISCREG_DR1: + case MISCREG_DR2: + case MISCREG_DR3: + /* These should eventually set up breakpoints. */ + break; + case MISCREG_DR4: + miscReg = MISCREG_DR6; + /* Fall through to have the same effects as DR6. */ + case MISCREG_DR6: + { + DR6 dr6 = regVal[MISCREG_DR6]; + DR6 newDR6 = val; + dr6.b0 = newDR6.b0; + dr6.b1 = newDR6.b1; + dr6.b2 = newDR6.b2; + dr6.b3 = newDR6.b3; + dr6.bd = newDR6.bd; + dr6.bs = newDR6.bs; + dr6.bt = newDR6.bt; + newVal = dr6; + } + break; + case MISCREG_DR5: + miscReg = MISCREG_DR7; + /* Fall through to have the same effects as DR7. */ + case MISCREG_DR7: + { + DR7 dr7 = regVal[MISCREG_DR7]; + DR7 newDR7 = val; + dr7.l0 = newDR7.l0; + dr7.g0 = newDR7.g0; + if (dr7.l0 || dr7.g0) { + panic("Debug register breakpoints not implemented.\n"); + } else { + /* Disable breakpoint 0. */ + } + dr7.l1 = newDR7.l1; + dr7.g1 = newDR7.g1; + if (dr7.l1 || dr7.g1) { + panic("Debug register breakpoints not implemented.\n"); + } else { + /* Disable breakpoint 1. */ + } + dr7.l2 = newDR7.l2; + dr7.g2 = newDR7.g2; + if (dr7.l2 || dr7.g2) { + panic("Debug register breakpoints not implemented.\n"); + } else { + /* Disable breakpoint 2. */ + } + dr7.l3 = newDR7.l3; + dr7.g3 = newDR7.g3; + if (dr7.l3 || dr7.g3) { + panic("Debug register breakpoints not implemented.\n"); + } else { + /* Disable breakpoint 3. */ + } + dr7.gd = newDR7.gd; + dr7.rw0 = newDR7.rw0; + dr7.len0 = newDR7.len0; + dr7.rw1 = newDR7.rw1; + dr7.len1 = newDR7.len1; + dr7.rw2 = newDR7.rw2; + dr7.len2 = newDR7.len2; + dr7.rw3 = newDR7.rw3; + dr7.len3 = newDR7.len3; + } + break; default: break; } -- cgit v1.2.3 From c39ed53d05be42a83b0bd9b4cc3e12fb8864f469 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:20:30 -0800 Subject: X86: Rename oszForPseudoDesc maxOsz to reflect its more general use. --- src/arch/x86/isa/insts/system/segmentation.py | 16 ++++++++-------- src/arch/x86/isa/microasm.isa | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/system/segmentation.py b/src/arch/x86/isa/insts/system/segmentation.py index 2de79f935..7c13765ca 100644 --- a/src/arch/x86/isa/insts/system/segmentation.py +++ b/src/arch/x86/isa/insts/system/segmentation.py @@ -56,7 +56,7 @@ microcode = ''' def macroop LGDT_M { - .adjust_env oszForPseudoDesc + .adjust_env maxOsz # Get the limit ld t1, seg, sib, disp, dataSize=2 @@ -68,7 +68,7 @@ def macroop LGDT_M def macroop LGDT_P { - .adjust_env oszForPseudoDesc + .adjust_env maxOsz rdip t7 # Get the limit @@ -86,7 +86,7 @@ def macroop LGDT_P def macroop LGDT_16_M { - .adjust_env oszForPseudoDesc + .adjust_env maxOsz # Get the limit ld t1, seg, sib, disp, dataSize=2 @@ -99,7 +99,7 @@ def macroop LGDT_16_M def macroop LGDT_16_P { - .adjust_env oszForPseudoDesc + .adjust_env maxOsz rdip t7 # Get the limit @@ -113,7 +113,7 @@ def macroop LGDT_16_P def macroop LIDT_M { - .adjust_env oszForPseudoDesc + .adjust_env maxOsz # Get the limit ld t1, seg, sib, disp, dataSize=2 @@ -125,7 +125,7 @@ def macroop LIDT_M def macroop LIDT_P { - .adjust_env oszForPseudoDesc + .adjust_env maxOsz rdip t7 # Get the limit @@ -143,7 +143,7 @@ def macroop LIDT_P def macroop LIDT_16_M { - .adjust_env oszForPseudoDesc + .adjust_env maxOsz # Get the limit ld t1, seg, sib, disp, dataSize=2 @@ -156,7 +156,7 @@ def macroop LIDT_16_M def macroop LIDT_16_P { - .adjust_env oszForPseudoDesc + .adjust_env maxOsz rdip t7 # Get the limit diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index fe1d38ff1..00baed768 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -173,7 +173,7 @@ let {{ env.dataSize = 8; ''' - assembler.symbols["oszForPseudoDesc"] = ''' + assembler.symbols["maxOsz"] = ''' if (machInst.mode.submode == SixtyFourBitMode) env.dataSize = 8; else -- cgit v1.2.3 From 28efb3c6e3c13b9673e9077fcc9d54d2d512f72a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:20:42 -0800 Subject: X86: Implement the mov to debug register intructions. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 4 ++-- src/arch/x86/isa/insts/general_purpose/data_transfer/move.py | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index edacf5bcb..f4a007282 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -352,9 +352,9 @@ // no prefix 0x0: decode OPCODE_OP_BOTTOM3 { 0x0: Inst::MOV(Rd,Cd); - 0x1: mov_Rd_Dd(); + 0x1: Inst::MOV(Rd,Dd); 0x2: Inst::MOV(Cd,Rd); - 0x3: mov_Dd_Rd(); + 0x3: Inst::MOV(Dd,Rd); 0x4: mov_Rd_Td(); 0x6: mov_Td_Rd(); default: Inst::UD2(); diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py index 82c076216..abe44ae59 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py @@ -199,6 +199,16 @@ def macroop MOV_R_C { rdcr reg, regm }; +def macroop MOV_D_R { + .adjust_env maxOsz + wrdr reg, regm +}; + +def macroop MOV_R_D { + .adjust_env maxOsz + rddr reg, regm +}; + def macroop MOV_R_S { rdsel reg, regm }; -- cgit v1.2.3 From b035c917a5e0749cb4068d2de66331beda52d222 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:20:47 -0800 Subject: X86: Make the segment register reading microops use merge. --- .../general_purpose/control_transfer/interrupts_and_exceptions.py | 2 +- src/arch/x86/isa/microops/regop.isa | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py index 8d66cc445..8203f7c2c 100644 --- a/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py +++ b/src/arch/x86/isa/insts/general_purpose/control_transfer/interrupts_and_exceptions.py @@ -142,7 +142,7 @@ processCSDescriptor: # Here, we know we're -not- in 64 bit mode, so we should do the # appropriate/other RIP checks. # if temp_RIP > CS.limit throw #GP(0) - rdlimit t6, cs + rdlimit t6, cs, dataSize=8 subi t0, t1, t6, flags=(ECF,) fault "new GeneralProtection(0)", flags=(CECF,) diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index fd2a3a64f..1349a64c2 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -1052,22 +1052,22 @@ let {{ class Rdbase(SegOp): code = ''' - DestReg = SegBaseSrc1; + DestReg = merge(DestReg, SegBaseSrc1, dataSize); ''' class Rdlimit(SegOp): code = ''' - DestReg = SegLimitSrc1; + DestReg = merge(DestReg, SegLimitSrc1, dataSize); ''' class RdAttr(SegOp): code = ''' - DestReg = SegAttrSrc1; + DestReg = merge(DestReg, SegAttrSrc1, dataSize); ''' class Rdsel(SegOp): code = ''' - DestReg = SegSelSrc1; + DestReg = merge(DestReg, SegSelSrc1, dataSize); ''' class Rdval(RegOp): -- cgit v1.2.3 From 9842f1ca9d3de48d6bc990248be14b119dca9891 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:21:02 -0800 Subject: X86: Implement CLTS. --- src/arch/x86/SConscript | 1 + src/arch/x86/isa/decoder/two_byte_opcodes.isa | 2 +- src/arch/x86/isa/insts/system/__init__.py | 3 +- src/arch/x86/isa/insts/system/control_registers.py | 35 ++++++++++++++++++++++ 4 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 src/arch/x86/isa/insts/system/control_registers.py (limited to 'src/arch') diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript index 0e13d3104..4c0460e28 100644 --- a/src/arch/x86/SConscript +++ b/src/arch/x86/SConscript @@ -190,6 +190,7 @@ if env['TARGET_ISA'] == 'x86': 'general_purpose/system_calls.py', 'romutil.py', 'system/__init__.py', + 'system/control_registers.py', 'system/halt.py', 'system/invlpg.py', 'system/undefined_operation.py', diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index f4a007282..c127ff458 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -264,7 +264,7 @@ #else 0x05: SyscallInst::syscall('xc->syscall(Rax)', IsSyscall); #endif - 0x06: clts(); + 0x06: Inst::CLTS(); 0x07: decode MODE_SUBMODE { 0x0: decode OPSIZE { // Return to 64 bit mode. diff --git a/src/arch/x86/isa/insts/system/__init__.py b/src/arch/x86/isa/insts/system/__init__.py index 409a929f5..0dec9ebda 100644 --- a/src/arch/x86/isa/insts/system/__init__.py +++ b/src/arch/x86/isa/insts/system/__init__.py @@ -81,7 +81,8 @@ # # Authors: Gabe Black -categories = ["halt", +categories = ["control_registers", + "halt", "invlpg", "undefined_operation", "msrs", diff --git a/src/arch/x86/isa/insts/system/control_registers.py b/src/arch/x86/isa/insts/system/control_registers.py new file mode 100644 index 000000000..902c01abb --- /dev/null +++ b/src/arch/x86/isa/insts/system/control_registers.py @@ -0,0 +1,35 @@ +# Copyright (c) 2009 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Gabe Black + +microcode = ''' +def macroop CLTS { + rdcr t1, 0, dataSize=8 + andi t1, t1, 0xF7, dataSize=1 + wrcr 0, t1, dataSize=8 +}; +''' -- cgit v1.2.3 From 68300cfb8c6099cc84cb3e544950c0e6a154ff07 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:21:08 -0800 Subject: X86: Make rdcr use merge and the mov to control register instructions use the right operand size. --- src/arch/x86/isa/insts/general_purpose/data_transfer/move.py | 2 ++ src/arch/x86/isa/microops/regop.isa | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py index abe44ae59..dded94968 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py @@ -192,10 +192,12 @@ def macroop MOVZX_W_R_P { }; def macroop MOV_C_R { + .adjust_env maxOsz wrcr reg, regm }; def macroop MOV_R_C { + .adjust_env maxOsz rdcr reg, regm }; diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 1349a64c2..7c2feb398 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -967,7 +967,7 @@ let {{ if (src1 == 1 || (src1 > 4 && src1 < 8) || (src1 > 8)) { fault = new InvalidOpcode(); } else { - DestReg = ControlSrc1; + DestReg = merge(DestReg, ControlSrc1, dataSize); } ''' -- cgit v1.2.3 From e08d60389d8ddbe64d22834dbd327229822dac10 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:21:14 -0800 Subject: X86: Make the TSS type check actually return a fault if it fails. --- src/arch/x86/isa/microops/regop.isa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index 7c2feb398..d5eb59f11 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -1171,7 +1171,7 @@ let {{ } else if (!(desc.type == 0x9 || (desc.type == 1 && m5reg.mode != LongMode))) { - + fault = new GeneralProtection(selector); } break; default: -- cgit v1.2.3 From bda7077c6408542f0a1d766019b91a0c8eb2147b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:21:21 -0800 Subject: X86: Add segmentation checks for ldt related descriptors and selectors. --- src/arch/x86/isa/microasm.isa | 2 +- src/arch/x86/isa/microops/regop.isa | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microasm.isa b/src/arch/x86/isa/microasm.isa index 00baed768..c7c6dae2e 100644 --- a/src/arch/x86/isa/microasm.isa +++ b/src/arch/x86/isa/microasm.isa @@ -87,7 +87,7 @@ let {{ # Add in symbols for the various checks of segment selectors. for check in ("NoCheck", "CSCheck", "CallGateCheck", "IntGateCheck", "SoftIntGateCheck", "SSCheck", "IretCheck", "IntCSCheck", - "TRCheck", "TSSCheck"): + "TRCheck", "TSSCheck", "InGDTCheck", "LDTCheck"): assembler.symbols[check] = "Seg%s" % check for reg in ("TR", "IDTR"): diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index d5eb59f11..f9bc82119 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -235,7 +235,7 @@ output header {{ enum SegmentSelectorCheck { SegNoCheck, SegCSCheck, SegCallGateCheck, SegIntGateCheck, SegSoftIntGateCheck, SegSSCheck, SegIretCheck, SegIntCSCheck, - SegTRCheck, SegTSSCheck + SegTRCheck, SegTSSCheck, SegInGDTCheck, SegLDTCheck }; enum LongModeDescriptorType { @@ -1174,6 +1174,18 @@ let {{ fault = new GeneralProtection(selector); } break; + case SegInGDTCheck: + if (selector.ti) { + fault = new GeneralProtection(selector); + } + break; + case SegLDTCheck: + if (!desc.p) { + fault = new SegmentNotPresent(selector); + } else if (desc.type != 0x2) { + fault = new GeneralProtection(selector); + } + break; default: panic("Undefined segment check type.\\n"); } -- cgit v1.2.3 From 7aa875f4f3598c8ca6e3ba8946cf6eb3697a7696 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:21:27 -0800 Subject: X86: Implement the lldt instruction. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 2 +- src/arch/x86/isa/insts/system/segmentation.py | 51 +++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index c127ff458..9c376e2c4 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -93,7 +93,7 @@ 0x00: decode MODRM_REG { 0x0: sldt_Mw_or_Rv(); 0x1: str_Mw_or_Rv(); - 0x2: lldt_Mw_or_Rv(); + 0x2: Inst::LLDT(Ew); 0x3: Inst::LTR(Ew); 0x4: verr_Mw_or_Rv(); 0x5: verw_Mw_or_Rv(); diff --git a/src/arch/x86/isa/insts/system/segmentation.py b/src/arch/x86/isa/insts/system/segmentation.py index 7c13765ca..acbca9f6e 100644 --- a/src/arch/x86/isa/insts/system/segmentation.py +++ b/src/arch/x86/isa/insts/system/segmentation.py @@ -216,6 +216,57 @@ def macroop LTR_P st t1, tsg, [8, t4, t0], dataSize=8 }; +def macroop LLDT_R +{ + chks reg, t0, InGDTCheck, flags=(EZF,) + br label("end"), flags=(CEZF,) + limm t4, 0 + srli t4, reg, 3, dataSize=2 + ldst t1, tsg, [8, t4, t0], dataSize=8 + ld t2, tsg, [8, t4, t0], 8, dataSize=8 + chks reg, t1, LDTCheck + wrdh t3, t1, t2 + wrdl tr, t1, reg + wrbase tr, t3, dataSize=8 +end: + fault "NoFault" +}; + +def macroop LLDT_M +{ + ld t5, seg, sib, disp, dataSize=2 + chks t5, t0, InGDTCheck, flags=(EZF,) + br label("end"), flags=(CEZF,) + limm t4, 0 + srli t4, t5, 3, dataSize=2 + ldst t1, tsg, [8, t4, t0], dataSize=8 + ld t2, tsg, [8, t4, t0], 8, dataSize=8 + chks t5, t1, LDTCheck + wrdh t3, t1, t2 + wrdl tr, t1, t5 + wrbase tr, t3, dataSize=8 +end: + fault "NoFault" +}; + +def macroop LLDT_P +{ + rdip t7 + ld t5, seg, riprel, disp, dataSize=2 + chks t5, t0, InGDTCheck, flags=(EZF,) + br label("end"), flags=(CEZF,) + limm t4, 0 + srli t4, t5, 3, dataSize=2 + ldst t1, tsg, [8, t4, t0], dataSize=8 + ld t2, tsg, [8, t4, t0], 8, dataSize=8 + chks t5, t1, LDTCheck + wrdh t3, t1, t2 + wrdl tr, t1, t5 + wrbase tr, t3, dataSize=8 +end: + fault "NoFault" +}; + def macroop SWAPGS { rdval t1, kernel_gs_base, dataSize=8 -- cgit v1.2.3 From 88ee7d4c32854608a9887ecbd60139dc20ab1974 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:21:33 -0800 Subject: SPARC: Add a traceflag for register windows. --- src/arch/sparc/SConscript | 1 + src/arch/sparc/intregfile.cc | 6 +++--- src/arch/sparc/regfile.cc | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) (limited to 'src/arch') diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript index 148277358..940cf2076 100644 --- a/src/arch/sparc/SConscript +++ b/src/arch/sparc/SConscript @@ -45,6 +45,7 @@ if env['TARGET_ISA'] == 'sparc': SimObject('SparcTLB.py') TraceFlag('Sparc', "Generic SPARC ISA stuff") + TraceFlag('RegisterWindows', "Register window manipulation") if env['FULL_SYSTEM']: SimObject('SparcSystem.py') diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc index 39a613a0d..6419f0f93 100644 --- a/src/arch/sparc/intregfile.cc +++ b/src/arch/sparc/intregfile.cc @@ -55,7 +55,7 @@ int IntRegFile::flattenIndex(int reg) { int flatIndex = offset[reg >> FrameOffsetBits] | (reg & FrameOffsetMask); - DPRINTF(Sparc, "Flattened index %d into %d.\n", reg, flatIndex); + DPRINTF(RegisterWindows, "Flattened index %d into %d.\n", reg, flatIndex); return flatIndex; } @@ -135,12 +135,12 @@ void IntRegFile::setCWP(int cwp) regView[Locals] = regSegments[index+1]; regView[Inputs] = regSegments[(index+2) % (NWindows * 2)]; - DPRINTF(Sparc, "Changed the CWP value to %d\n", cwp); + DPRINTF(RegisterWindows, "Changed the CWP value to %d\n", cwp); } void IntRegFile::setGlobals(int gl) { - DPRINTF(Sparc, "Now using %d globals\n", gl); + DPRINTF(RegisterWindows, "Now using %d globals\n", gl); regView[Globals] = regGlobals[gl]; offset[Globals] = RegGlobalOffset + gl * RegsPerFrame; diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc index f390be508..1c172a4d5 100644 --- a/src/arch/sparc/regfile.cc +++ b/src/arch/sparc/regfile.cc @@ -155,7 +155,7 @@ int SparcISA::flattenIntIndex(ThreadContext * tc, int reg) { int gl = tc->readMiscRegNoEffect(MISCREG_GL); int cwp = tc->readMiscRegNoEffect(MISCREG_CWP); - //DPRINTF(Sparc, "Global Level = %d, Current Window Pointer = %d\n", gl, cwp); + //DPRINTF(RegisterWindows, "Global Level = %d, Current Window Pointer = %d\n", gl, cwp); int newReg; //The total number of global registers int numGlobals = (MaxGL + 1) * 8; @@ -214,7 +214,7 @@ int SparcISA::flattenIntIndex(ThreadContext * tc, int reg) } else panic("Tried to flatten invalid register index %d!\n", reg); - DPRINTF(Sparc, "Flattened register %d to %d.\n", reg, newReg); + DPRINTF(RegisterWindows, "Flattened register %d to %d.\n", reg, newReg); return newReg; //return intRegFile.flattenIndex(reg); } -- cgit v1.2.3 From f41ce6b5e9d606826c9519cf355f992f53bb4dbf Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:21:40 -0800 Subject: SPARC: Get rid of the setCWP function. --- src/arch/sparc/intregfile.cc | 20 -------------------- src/arch/sparc/intregfile.hh | 5 ----- 2 files changed, 25 deletions(-) (limited to 'src/arch') diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc index 6419f0f93..28299c9b3 100644 --- a/src/arch/sparc/intregfile.cc +++ b/src/arch/sparc/intregfile.cc @@ -73,7 +73,6 @@ IntRegFile::IntRegFile() { offset[Globals] = 0; regView[Globals] = regGlobals[0]; - setCWP(0); clear(); } @@ -119,25 +118,6 @@ void IntRegFile::setReg(int intReg, const IntReg &val) } */ } -//This doesn't effect the actual CWP register. -//It's purpose is to adjust the view of the register file -//to what it would be if CWP = cwp. -void IntRegFile::setCWP(int cwp) -{ - int index = ((NWindows - cwp) % NWindows) * 2; - if (index < 0) - panic("Index less than 0. cwp=%d nwin=%d\n", cwp, NWindows); - offset[Outputs] = FrameOffset + (index * RegsPerFrame); - offset[Locals] = FrameOffset + ((index+1) * RegsPerFrame); - offset[Inputs] = FrameOffset + - (((index+2) % (NWindows * 2)) * RegsPerFrame); - regView[Outputs] = regSegments[index]; - regView[Locals] = regSegments[index+1]; - regView[Inputs] = regSegments[(index+2) % (NWindows * 2)]; - - DPRINTF(RegisterWindows, "Changed the CWP value to %d\n", cwp); -} - void IntRegFile::setGlobals(int gl) { DPRINTF(RegisterWindows, "Now using %d globals\n", gl); diff --git a/src/arch/sparc/intregfile.hh b/src/arch/sparc/intregfile.hh index 83ef1d17b..0d1fe413e 100644 --- a/src/arch/sparc/intregfile.hh +++ b/src/arch/sparc/intregfile.hh @@ -102,11 +102,6 @@ namespace SparcISA void unserialize(Checkpoint *cp, const std::string §ion); protected: - //This doesn't effect the actual CWP register. - //It's purpose is to adjust the view of the register file - //to what it would be if CWP = cwp. - void setCWP(int cwp); - void setGlobals(int gl); }; } -- cgit v1.2.3 From 9d5b6e377ffca79e0dabe3fb63215d2f51a4eb7b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:21:46 -0800 Subject: SPARC: Get rid of the setGlobals function. --- src/arch/sparc/intregfile.cc | 13 ------------- src/arch/sparc/intregfile.hh | 3 --- 2 files changed, 16 deletions(-) (limited to 'src/arch') diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc index 28299c9b3..26637ddad 100644 --- a/src/arch/sparc/intregfile.cc +++ b/src/arch/sparc/intregfile.cc @@ -118,19 +118,6 @@ void IntRegFile::setReg(int intReg, const IntReg &val) } */ } -void IntRegFile::setGlobals(int gl) -{ - DPRINTF(RegisterWindows, "Now using %d globals\n", gl); - - regView[Globals] = regGlobals[gl]; - offset[Globals] = RegGlobalOffset + gl * RegsPerFrame; - - if (regView[Globals] == regView[Inputs] || - regView[Globals] == regView[Locals] || - regView[Globals] == regView[Outputs] ) - panic("Two register arrays set to the same thing!\n"); -} - void IntRegFile::serialize(std::ostream &os) { SERIALIZE_ARRAY(regs, NumIntRegs); diff --git a/src/arch/sparc/intregfile.hh b/src/arch/sparc/intregfile.hh index 0d1fe413e..ce9bcadb6 100644 --- a/src/arch/sparc/intregfile.hh +++ b/src/arch/sparc/intregfile.hh @@ -100,9 +100,6 @@ namespace SparcISA void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); - - protected: - void setGlobals(int gl); }; } -- cgit v1.2.3 From ce2e50a64cf69a41e030e8c3ba8a53612dd32c48 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:21:52 -0800 Subject: ISA: Use the "Stack" traceflag for DPRINTFs about the initial stack frame. --- src/arch/sparc/process.cc | 24 ++++++++++++------------ src/arch/x86/process.cc | 20 ++++++++++---------- 2 files changed, 22 insertions(+), 22 deletions(-) (limited to 'src/arch') diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 91baea40c..515389687 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -338,18 +338,18 @@ SparcLiveProcess::argsInit(int pageSize) IntType window_save_base = argc_base - window_save_size; #endif - DPRINTF(Sparc, "The addresses of items on the initial stack:\n"); - DPRINTF(Sparc, "%#x - sentry NULL\n", sentry_base); - DPRINTF(Sparc, "filename = %s\n", filename); - DPRINTF(Sparc, "%#x - file name\n", file_name_base); - DPRINTF(Sparc, "%#x - env data\n", env_data_base); - DPRINTF(Sparc, "%#x - arg data\n", arg_data_base); - DPRINTF(Sparc, "%#x - auxv array\n", auxv_array_base); - DPRINTF(Sparc, "%#x - envp array\n", envp_array_base); - DPRINTF(Sparc, "%#x - argv array\n", argv_array_base); - DPRINTF(Sparc, "%#x - argc \n", argc_base); - DPRINTF(Sparc, "%#x - window save\n", window_save_base); - DPRINTF(Sparc, "%#x - stack min\n", stack_min); + DPRINTF(Stack, "The addresses of items on the initial stack:\n"); + DPRINTF(Stack, "%#x - sentry NULL\n", sentry_base); + DPRINTF(Stack, "filename = %s\n", filename); + DPRINTF(Stack, "%#x - file name\n", file_name_base); + DPRINTF(Stack, "%#x - env data\n", env_data_base); + DPRINTF(Stack, "%#x - arg data\n", arg_data_base); + DPRINTF(Stack, "%#x - auxv array\n", auxv_array_base); + DPRINTF(Stack, "%#x - envp array\n", envp_array_base); + DPRINTF(Stack, "%#x - argv array\n", argv_array_base); + DPRINTF(Stack, "%#x - argc \n", argc_base); + DPRINTF(Stack, "%#x - window save\n", window_save_base); + DPRINTF(Stack, "%#x - stack min\n", stack_min); assert(window_save_base == stack_min); diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 2013190eb..d6f3b2371 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -406,16 +406,16 @@ X86LiveProcess::argsInit(int intSize, int pageSize) Addr argv_array_base = envp_array_base - argv_array_size; Addr argc_base = argv_array_base - argc_size; - DPRINTF(X86, "The addresses of items on the initial stack:\n"); - DPRINTF(X86, "0x%x - file name\n", file_name_base); - DPRINTF(X86, "0x%x - env data\n", env_data_base); - DPRINTF(X86, "0x%x - arg data\n", arg_data_base); - DPRINTF(X86, "0x%x - aux data\n", aux_data_base); - DPRINTF(X86, "0x%x - auxv array\n", auxv_array_base); - DPRINTF(X86, "0x%x - envp array\n", envp_array_base); - DPRINTF(X86, "0x%x - argv array\n", argv_array_base); - DPRINTF(X86, "0x%x - argc \n", argc_base); - DPRINTF(X86, "0x%x - stack min\n", stack_min); + DPRINTF(Stack, "The addresses of items on the initial stack:\n"); + DPRINTF(Stack, "0x%x - file name\n", file_name_base); + DPRINTF(Stack, "0x%x - env data\n", env_data_base); + DPRINTF(Stack, "0x%x - arg data\n", arg_data_base); + DPRINTF(Stack, "0x%x - aux data\n", aux_data_base); + DPRINTF(Stack, "0x%x - auxv array\n", auxv_array_base); + DPRINTF(Stack, "0x%x - envp array\n", envp_array_base); + DPRINTF(Stack, "0x%x - argv array\n", argv_array_base); + DPRINTF(Stack, "0x%x - argc \n", argc_base); + DPRINTF(Stack, "0x%x - stack min\n", stack_min); // write contents to stack -- cgit v1.2.3 From c1c61d52a0d7e00361fb6fa69fd7c4ea2f528de8 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:21:59 -0800 Subject: SPARC: Get rid of flattenIndex in the int register file. --- src/arch/sparc/intregfile.cc | 8 -------- src/arch/sparc/intregfile.hh | 2 -- 2 files changed, 10 deletions(-) (limited to 'src/arch') diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc index 26637ddad..c111172a9 100644 --- a/src/arch/sparc/intregfile.cc +++ b/src/arch/sparc/intregfile.cc @@ -51,14 +51,6 @@ string SparcISA::getIntRegName(RegIndex index) return intRegName[index]; } -int IntRegFile::flattenIndex(int reg) -{ - int flatIndex = offset[reg >> FrameOffsetBits] - | (reg & FrameOffsetMask); - DPRINTF(RegisterWindows, "Flattened index %d into %d.\n", reg, flatIndex); - return flatIndex; -} - void IntRegFile::clear() { int x; diff --git a/src/arch/sparc/intregfile.hh b/src/arch/sparc/intregfile.hh index ce9bcadb6..9a086f08a 100644 --- a/src/arch/sparc/intregfile.hh +++ b/src/arch/sparc/intregfile.hh @@ -87,8 +87,6 @@ namespace SparcISA public: - int flattenIndex(int reg); - void clear(); IntRegFile(); -- cgit v1.2.3 From 44d5351071d3f9ec80f2fab7876d757cfbd5bacf Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:22:09 -0800 Subject: ISA: Get rid of FlattenIntIndex function. --- src/arch/sparc/regfile.hh | 2 -- src/arch/x86/regfile.hh | 2 -- 2 files changed, 4 deletions(-) (limited to 'src/arch') diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh index dd4e1f684..505d7c8d7 100644 --- a/src/arch/sparc/regfile.hh +++ b/src/arch/sparc/regfile.hh @@ -71,8 +71,6 @@ namespace SparcISA void clear(); - int FlattenIntIndex(int reg); - MiscReg readMiscRegNoEffect(int miscReg); MiscReg readMiscReg(int miscReg, ThreadContext *tc); diff --git a/src/arch/x86/regfile.hh b/src/arch/x86/regfile.hh index 75c0290d3..8938ab0bc 100644 --- a/src/arch/x86/regfile.hh +++ b/src/arch/x86/regfile.hh @@ -97,8 +97,6 @@ namespace X86ISA void clear(); - int FlattenIntIndex(int reg); - MiscReg readMiscRegNoEffect(int miscReg); MiscReg readMiscReg(int miscReg, ThreadContext *tc); -- cgit v1.2.3 From 4633677145225a76ee3826ef97a24b1e427f61f8 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:22:17 -0800 Subject: ISA: Set up common trace flags for tracing registers. --- src/arch/SConscript | 5 +++++ src/arch/sparc/floatregfile.cc | 24 ++++++++++++++++-------- src/arch/sparc/intregfile.cc | 8 ++++---- src/arch/sparc/miscregfile.cc | 4 ++-- src/arch/x86/floatregfile.cc | 8 ++++---- src/arch/x86/intregfile.cc | 6 ++++-- 6 files changed, 35 insertions(+), 20 deletions(-) (limited to 'src/arch') diff --git a/src/arch/SConscript b/src/arch/SConscript index 932cf7509..2b0af2816 100644 --- a/src/arch/SConscript +++ b/src/arch/SConscript @@ -126,3 +126,8 @@ else: emitter = isa_desc_emitter) env.Append(BUILDERS = { 'ISADesc' : isa_desc_builder }) + +TraceFlag('IntRegs') +TraceFlag('FloatRegs') +TraceFlag('MiscRegs') +CompoundFlag('Registers', [ 'IntRegs', 'FloatRegs', 'MiscRegs' ]) diff --git a/src/arch/sparc/floatregfile.cc b/src/arch/sparc/floatregfile.cc index e1b5ea7c8..cf33b6a77 100644 --- a/src/arch/sparc/floatregfile.cc +++ b/src/arch/sparc/floatregfile.cc @@ -75,7 +75,8 @@ FloatReg FloatRegFile::readReg(int floatReg, int width) result32 = htog(result32); memcpy(&fresult32, &result32, sizeof(result32)); result = fresult32; - DPRINTF(Sparc, "Read FP32 register %d = [%f]0x%x\n", floatReg, result, result32); + DPRINTF(FloatRegs, "Read FP32 register %d = [%f]0x%x\n", + floatReg, result, result32); break; case DoubleWidth: uint64_t result64; @@ -84,7 +85,8 @@ FloatReg FloatRegFile::readReg(int floatReg, int width) result64 = htog(result64); memcpy(&fresult64, &result64, sizeof(result64)); result = fresult64; - DPRINTF(Sparc, "Read FP64 register %d = [%f]0x%x\n", floatReg, result, result64); + DPRINTF(FloatRegs, "Read FP64 register %d = [%f]0x%x\n", + floatReg, result, result64); break; case QuadWidth: panic("Quad width FP not implemented."); @@ -107,13 +109,15 @@ FloatRegBits FloatRegFile::readRegBits(int floatReg, int width) uint32_t result32; memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32)); result = htog(result32); - DPRINTF(Sparc, "Read FP32 bits register %d = 0x%x\n", floatReg, result); + DPRINTF(FloatRegs, "Read FP32 bits register %d = 0x%x\n", + floatReg, result); break; case DoubleWidth: uint64_t result64; memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64)); result = htog(result64); - DPRINTF(Sparc, "Read FP64 bits register %d = 0x%x\n", floatReg, result); + DPRINTF(FloatRegs, "Read FP64 bits register %d = 0x%x\n", + floatReg, result); break; case QuadWidth: panic("Quad width FP not implemented."); @@ -141,14 +145,16 @@ Fault FloatRegFile::setReg(int floatReg, const FloatReg &val, int width) memcpy(&result32, &fresult32, sizeof(result32)); result32 = gtoh(result32); memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32)); - DPRINTF(Sparc, "Write FP64 register %d = 0x%x\n", floatReg, result32); + DPRINTF(FloatRegs, "Write FP64 register %d = 0x%x\n", + floatReg, result32); break; case DoubleWidth: fresult64 = val; memcpy(&result64, &fresult64, sizeof(result64)); result64 = gtoh(result64); memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64)); - DPRINTF(Sparc, "Write FP64 register %d = 0x%x\n", floatReg, result64); + DPRINTF(FloatRegs, "Write FP64 register %d = 0x%x\n", + floatReg, result64); break; case QuadWidth: panic("Quad width FP not implemented."); @@ -171,12 +177,14 @@ Fault FloatRegFile::setRegBits(int floatReg, const FloatRegBits &val, int width) case SingleWidth: result32 = gtoh((uint32_t)val); memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32)); - DPRINTF(Sparc, "Write FP64 bits register %d = 0x%x\n", floatReg, result32); + DPRINTF(FloatRegs, "Write FP64 bits register %d = 0x%x\n", + floatReg, result32); break; case DoubleWidth: result64 = gtoh((uint64_t)val); memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64)); - DPRINTF(Sparc, "Write FP64 bits register %d = 0x%x\n", floatReg, result64); + DPRINTF(FloatRegs, "Write FP64 bits register %d = 0x%x\n", + floatReg, result64); break; case QuadWidth: panic("Quad width FP not implemented."); diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc index c111172a9..7c20d5169 100644 --- a/src/arch/sparc/intregfile.cc +++ b/src/arch/sparc/intregfile.cc @@ -70,7 +70,7 @@ IntRegFile::IntRegFile() IntReg IntRegFile::readReg(int intReg) { - DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, regs[intReg]); + DPRINTF(IntRegs, "Read register %d = 0x%x\n", intReg, regs[intReg]); return regs[intReg]; /* XXX Currently not used. When used again regView/offset need to be * serialized! @@ -83,7 +83,7 @@ IntReg IntRegFile::readReg(int intReg) panic("Tried to read non-existant integer register %d, %d\n", NumIntArchRegs + NumMicroIntRegs + intReg, intReg); - DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, val); + DPRINTF(IntRegs, "Read register %d = 0x%x\n", intReg, val); return val; */ } @@ -92,7 +92,7 @@ void IntRegFile::setReg(int intReg, const IntReg &val) { if(intReg) { - DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val); + DPRINTF(IntRegs, "Wrote register %d = 0x%x\n", intReg, val); regs[intReg] = val; } return; @@ -100,7 +100,7 @@ void IntRegFile::setReg(int intReg, const IntReg &val) * serialized! if(intReg) { - DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val); + DPRINTF(IntRegs, "Wrote register %d = 0x%x\n", intReg, val); if(intReg < NumIntArchRegs) regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val; else if((intReg -= NumIntArchRegs) < NumMicroIntRegs) diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index b22ceb657..e06d4b15a 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -227,7 +227,7 @@ MiscReg MiscRegFile::readRegNoEffect(int miscReg) /** Floating Point Status Register */ case MISCREG_FSR: - DPRINTF(Sparc, "FSR read as: %#x\n", fsr); + DPRINTF(MiscRegs, "FSR read as: %#x\n", fsr); return fsr; case MISCREG_MMU_P_CONTEXT: @@ -446,7 +446,7 @@ void MiscRegFile::setRegNoEffect(int miscReg, const MiscReg &val) /** Floating Point Status Register */ case MISCREG_FSR: fsr = val; - DPRINTF(Sparc, "FSR written with: %#x\n", fsr); + DPRINTF(MiscRegs, "FSR written with: %#x\n", fsr); break; case MISCREG_MMU_P_CONTEXT: diff --git a/src/arch/x86/floatregfile.cc b/src/arch/x86/floatregfile.cc index 1c49ea9c6..da5372c69 100644 --- a/src/arch/x86/floatregfile.cc +++ b/src/arch/x86/floatregfile.cc @@ -113,27 +113,27 @@ void FloatRegFile::clear() FloatReg FloatRegFile::readReg(int floatReg, int width) { FloatReg reg = d[floatReg]; - DPRINTF(X86, "Reading %f from register %d.\n", reg, floatReg); + DPRINTF(FloatRegs, "Reading %f from register %d.\n", reg, floatReg); return reg; } FloatRegBits FloatRegFile::readRegBits(int floatReg, int width) { FloatRegBits reg = q[floatReg]; - DPRINTF(X86, "Reading %#x from register %d.\n", reg, floatReg); + DPRINTF(FloatRegs, "Reading %#x from register %d.\n", reg, floatReg); return reg; } Fault FloatRegFile::setReg(int floatReg, const FloatReg &val, int width) { - DPRINTF(X86, "Writing %f to register %d.\n", val, floatReg); + DPRINTF(FloatRegs, "Writing %f to register %d.\n", val, floatReg); d[floatReg] = val; return NoFault; } Fault FloatRegFile::setRegBits(int floatReg, const FloatRegBits &val, int width) { - DPRINTF(X86, "Writing bits %#x to register %d.\n", val, floatReg); + DPRINTF(FloatRegs, "Writing bits %#x to register %d.\n", val, floatReg); q[floatReg] = val; return NoFault; } diff --git a/src/arch/x86/intregfile.cc b/src/arch/x86/intregfile.cc index 9c9ea134e..43cfb8082 100644 --- a/src/arch/x86/intregfile.cc +++ b/src/arch/x86/intregfile.cc @@ -120,13 +120,15 @@ void IntRegFile::clear() IntReg IntRegFile::readReg(int intReg) { - DPRINTF(X86, "Read int reg %d and got value %#x\n", intReg, regs[intReg]); + DPRINTF(IntRegs, "Read int reg %d and got value %#x\n", + intReg, regs[intReg]); return regs[intReg]; } void IntRegFile::setReg(int intReg, const IntReg &val) { - DPRINTF(X86, "Setting int reg %d to value %#x\n", intReg, val); + DPRINTF(IntRegs, "Setting int reg %d to value %#x\n", + intReg, val); regs[intReg] = val; } -- cgit v1.2.3 From 3b01535ec1ea6f51738675b3caf36e3f100ad128 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:22:25 -0800 Subject: SPARC: Get rid of the state keeping track of register frames. --- src/arch/sparc/intregfile.cc | 47 -------------------------------------------- src/arch/sparc/intregfile.hh | 31 ----------------------------- 2 files changed, 78 deletions(-) (limited to 'src/arch') diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc index 7c20d5169..49e41ed93 100644 --- a/src/arch/sparc/intregfile.cc +++ b/src/arch/sparc/intregfile.cc @@ -53,18 +53,11 @@ string SparcISA::getIntRegName(RegIndex index) void IntRegFile::clear() { - int x; - for (x = 0; x < MaxGL; x++) - memset(regGlobals[x], 0, sizeof(IntReg) * RegsPerFrame); - for(int x = 0; x < 2 * NWindows; x++) - memset(regSegments[x], 0, sizeof(IntReg) * RegsPerFrame); memset(regs, 0, sizeof(IntReg) * NumIntRegs); } IntRegFile::IntRegFile() { - offset[Globals] = 0; - regView[Globals] = regGlobals[0]; clear(); } @@ -72,20 +65,6 @@ IntReg IntRegFile::readReg(int intReg) { DPRINTF(IntRegs, "Read register %d = 0x%x\n", intReg, regs[intReg]); return regs[intReg]; - /* XXX Currently not used. When used again regView/offset need to be - * serialized! - IntReg val; - if(intReg < NumIntArchRegs) - val = regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask]; - else if((intReg -= NumIntArchRegs) < NumMicroIntRegs) - val = microRegs[intReg]; - else - panic("Tried to read non-existant integer register %d, %d\n", - NumIntArchRegs + NumMicroIntRegs + intReg, intReg); - - DPRINTF(IntRegs, "Read register %d = 0x%x\n", intReg, val); - return val; - */ } void IntRegFile::setReg(int intReg, const IntReg &val) @@ -96,42 +75,16 @@ void IntRegFile::setReg(int intReg, const IntReg &val) regs[intReg] = val; } return; - /* XXX Currently not used. When used again regView/offset need to be - * serialized! - if(intReg) - { - DPRINTF(IntRegs, "Wrote register %d = 0x%x\n", intReg, val); - if(intReg < NumIntArchRegs) - regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val; - else if((intReg -= NumIntArchRegs) < NumMicroIntRegs) - microRegs[intReg] = val; - else - panic("Tried to set non-existant integer register\n"); - } */ } void IntRegFile::serialize(std::ostream &os) { SERIALIZE_ARRAY(regs, NumIntRegs); SERIALIZE_ARRAY(microRegs, NumMicroIntRegs); - - /* the below doesn't seem needed unless gabe makes regview work*/ - unsigned int x; - for(x = 0; x < MaxGL; x++) - SERIALIZE_ARRAY(regGlobals[x], RegsPerFrame); - for(x = 0; x < 2 * NWindows; x++) - SERIALIZE_ARRAY(regSegments[x], RegsPerFrame); } void IntRegFile::unserialize(Checkpoint *cp, const std::string §ion) { UNSERIALIZE_ARRAY(regs, NumIntRegs); UNSERIALIZE_ARRAY(microRegs, NumMicroIntRegs); - - /* the below doesn't seem needed unless gabe makes regview work*/ - unsigned int x; - for(x = 0; x < MaxGL; x++) - UNSERIALIZE_ARRAY(regGlobals[x], RegsPerFrame); - for(unsigned int x = 0; x < 2 * NWindows; x++) - UNSERIALIZE_ARRAY(regSegments[x], RegsPerFrame); } diff --git a/src/arch/sparc/intregfile.hh b/src/arch/sparc/intregfile.hh index 9a086f08a..9bbb469ef 100644 --- a/src/arch/sparc/intregfile.hh +++ b/src/arch/sparc/intregfile.hh @@ -42,8 +42,6 @@ class Checkpoint; namespace SparcISA { - class RegFile; - //This function translates integer register file indices into names std::string getIntRegName(RegIndex); @@ -52,39 +50,10 @@ namespace SparcISA class IntRegFile { - private: - friend class RegFile; protected: - //The number of bits needed to index into each 8 register frame - static const int FrameOffsetBits = 3; - //The number of bits to choose between the 4 sets of 8 registers - static const int FrameNumBits = 2; - - //The number of registers per "frame" (8) - static const int RegsPerFrame = 1 << FrameOffsetBits; - //A mask to get the frame number - static const uint64_t FrameNumMask = - (FrameNumBits == sizeof(int)) ? - (unsigned int)(-1) : - (1 << FrameNumBits) - 1; - static const uint64_t FrameOffsetMask = - (FrameOffsetBits == sizeof(int)) ? - (unsigned int)(-1) : - (1 << FrameOffsetBits) - 1; - - IntReg regGlobals[MaxGL+1][RegsPerFrame]; - IntReg regSegments[2 * NWindows][RegsPerFrame]; IntReg microRegs[NumMicroIntRegs]; IntReg regs[NumIntRegs]; - enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames}; - - IntReg * regView[NumFrames]; - - static const int RegGlobalOffset = 0; - static const int FrameOffset = (MaxGL + 1) * RegsPerFrame; - int offset[NumFrames]; - public: void clear(); -- cgit v1.2.3 From 437b02884dedccc6f72f3e5d9c05d3a2dd6c6a2d Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:22:31 -0800 Subject: ISA: Get rid of the get*RegName functions. --- src/arch/alpha/floatregfile.hh | 6 ------ src/arch/alpha/intregfile.hh | 6 ------ src/arch/alpha/miscregfile.hh | 6 ------ src/arch/mips/regfile/float_regfile.hh | 5 ----- src/arch/mips/regfile/int_regfile.hh | 5 ----- src/arch/mips/regfile/misc_regfile.cc | 16 +++++----------- src/arch/mips/regfile/misc_regfile.hh | 2 -- src/arch/sparc/floatregfile.cc | 14 -------------- src/arch/sparc/floatregfile.hh | 2 -- src/arch/sparc/intregfile.cc | 10 ---------- src/arch/sparc/intregfile.hh | 3 --- src/arch/sparc/miscregfile.cc | 28 +++------------------------- src/arch/sparc/miscregfile.hh | 3 --- src/arch/sparc/ua2005.cc | 21 +++++++++++++++++++++ src/arch/x86/floatregfile.cc | 9 --------- src/arch/x86/floatregfile.hh | 2 -- src/arch/x86/intregfile.cc | 11 ----------- src/arch/x86/intregfile.hh | 3 --- src/arch/x86/miscregfile.cc | 6 ------ src/arch/x86/miscregfile.hh | 3 --- 20 files changed, 29 insertions(+), 132 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/floatregfile.hh b/src/arch/alpha/floatregfile.hh index 82592d80d..d5f9eec0f 100644 --- a/src/arch/alpha/floatregfile.hh +++ b/src/arch/alpha/floatregfile.hh @@ -42,12 +42,6 @@ class Checkpoint; namespace AlphaISA { -static inline std::string -getFloatRegName(RegIndex) -{ - return ""; -} - class FloatRegFile { public: diff --git a/src/arch/alpha/intregfile.hh b/src/arch/alpha/intregfile.hh index f6ba72e79..3aa7d92c4 100644 --- a/src/arch/alpha/intregfile.hh +++ b/src/arch/alpha/intregfile.hh @@ -41,12 +41,6 @@ class Checkpoint; namespace AlphaISA { -static inline std::string -getIntRegName(RegIndex) -{ - return ""; -} - // redirected register map, really only used for the full system case. extern const int reg_redir[NumIntRegs]; diff --git a/src/arch/alpha/miscregfile.hh b/src/arch/alpha/miscregfile.hh index 752099d01..6105ce683 100644 --- a/src/arch/alpha/miscregfile.hh +++ b/src/arch/alpha/miscregfile.hh @@ -53,12 +53,6 @@ enum MiscRegIndex MISCREG_INTR }; -static inline std::string -getMiscRegName(RegIndex) -{ - return ""; -} - class MiscRegFile { public: diff --git a/src/arch/mips/regfile/float_regfile.hh b/src/arch/mips/regfile/float_regfile.hh index 1537855df..0c0ecc7eb 100644 --- a/src/arch/mips/regfile/float_regfile.hh +++ b/src/arch/mips/regfile/float_regfile.hh @@ -44,11 +44,6 @@ class Checkpoint; namespace MipsISA { - static inline std::string getFloatRegName(RegIndex) - { - return ""; - } - const uint32_t MIPS32_QNAN = 0x7fbfffff; const uint64_t MIPS64_QNAN = ULL(0x7fbfffffffffffff); diff --git a/src/arch/mips/regfile/int_regfile.hh b/src/arch/mips/regfile/int_regfile.hh index 0f453a382..c5a6bb345 100644 --- a/src/arch/mips/regfile/int_regfile.hh +++ b/src/arch/mips/regfile/int_regfile.hh @@ -42,11 +42,6 @@ class Checkpoint; namespace MipsISA { - static inline std::string getIntRegName(RegIndex) - { - return ""; - } - enum MiscIntRegNums { LO = NumIntArchRegs, HI, diff --git a/src/arch/mips/regfile/misc_regfile.cc b/src/arch/mips/regfile/misc_regfile.cc index 08487db90..ea858abf0 100644 --- a/src/arch/mips/regfile/misc_regfile.cc +++ b/src/arch/mips/regfile/misc_regfile.cc @@ -437,12 +437,6 @@ MiscRegFile::reset(std::string core_name, unsigned num_threads, } -inline std::string -MipsISA::getMiscRegName(unsigned reg_idx) -{ - return MiscRegFile::miscRegNames[reg_idx]; -} - inline unsigned MiscRegFile::getVPENum(unsigned tid) { @@ -457,7 +451,7 @@ MiscRegFile::readRegNoEffect(int reg_idx, unsigned tid) unsigned reg_sel = (bankType[misc_reg] == perThreadContext) ? tid : getVPENum(tid); DPRINTF(MipsPRA, "Reading CP0 Register:%u Select:%u (%s) (%lx).\n", - misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg), + misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], miscRegFile[misc_reg][reg_sel]); return miscRegFile[misc_reg][reg_sel]; } @@ -474,7 +468,7 @@ MiscRegFile::readReg(int reg_idx, ? tid : getVPENum(tid); DPRINTF(MipsPRA, "Reading CP0 Register:%u Select:%u (%s) with effect (%lx).\n", - misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg), + misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], miscRegFile[misc_reg][reg_sel]); @@ -494,7 +488,7 @@ MiscRegFile::setRegNoEffect(int reg_idx, const MiscReg &val, unsigned tid) DPRINTF(MipsPRA, "[tid:%i]: Setting (direct set) CP0 Register:%u " "Select:%u (%s) to %#x.\n", - tid, misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg), val); + tid, misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], val); miscRegFile[misc_reg][reg_sel] = val; } @@ -507,7 +501,7 @@ MiscRegFile::setRegMask(int reg_idx, const MiscReg &val, unsigned tid) ? tid : getVPENum(tid); DPRINTF(MipsPRA, "[tid:%i]: Setting CP0 Register: %u Select: %u (%s) to %#x\n", - tid, misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg), val); + tid, misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], val); miscRegFile_WriteMask[misc_reg][reg_sel] = val; } @@ -527,7 +521,7 @@ MiscRegFile::setReg(int reg_idx, const MiscReg &val, DPRINTF(MipsPRA, "[tid:%i]: Setting CP0 Register:%u " "Select:%u (%s) to %#x, with effect.\n", - tid, misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg), val); + tid, misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], val); MiscReg cp0_val = filterCP0Write(misc_reg, reg_sel, val); diff --git a/src/arch/mips/regfile/misc_regfile.hh b/src/arch/mips/regfile/misc_regfile.hh index 4bec9a49e..c611d94cc 100644 --- a/src/arch/mips/regfile/misc_regfile.hh +++ b/src/arch/mips/regfile/misc_regfile.hh @@ -162,8 +162,6 @@ namespace MipsISA static std::string miscRegNames[NumMiscRegs]; }; - - inline std::string getMiscRegName(unsigned reg_idx); } // namespace MipsISA #endif diff --git a/src/arch/sparc/floatregfile.cc b/src/arch/sparc/floatregfile.cc index cf33b6a77..2d1af2218 100644 --- a/src/arch/sparc/floatregfile.cc +++ b/src/arch/sparc/floatregfile.cc @@ -41,20 +41,6 @@ using namespace std; class Checkpoint; -string SparcISA::getFloatRegName(RegIndex index) -{ - static std::string floatRegName[NumFloatRegs] = - {"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", - "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", - "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", - "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", - "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39", - "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47", - "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55", - "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63"}; - return floatRegName[index]; -} - void FloatRegFile::clear() { memset(regSpace, 0, sizeof(regSpace)); diff --git a/src/arch/sparc/floatregfile.hh b/src/arch/sparc/floatregfile.hh index 72803a5e0..265e71b4a 100644 --- a/src/arch/sparc/floatregfile.hh +++ b/src/arch/sparc/floatregfile.hh @@ -42,8 +42,6 @@ class Checkpoint; namespace SparcISA { - std::string getFloatRegName(RegIndex); - const int NumFloatArchRegs = 64; const int NumFloatRegs = 64; diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc index 49e41ed93..54c30d1cc 100644 --- a/src/arch/sparc/intregfile.cc +++ b/src/arch/sparc/intregfile.cc @@ -41,16 +41,6 @@ using namespace std; class Checkpoint; -string SparcISA::getIntRegName(RegIndex index) -{ - static std::string intRegName[NumIntArchRegs] = - {"g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", - "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7", - "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", - "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7"}; - return intRegName[index]; -} - void IntRegFile::clear() { memset(regs, 0, sizeof(IntReg) * NumIntRegs); diff --git a/src/arch/sparc/intregfile.hh b/src/arch/sparc/intregfile.hh index 9bbb469ef..f669f6b0d 100644 --- a/src/arch/sparc/intregfile.hh +++ b/src/arch/sparc/intregfile.hh @@ -42,9 +42,6 @@ class Checkpoint; namespace SparcISA { - //This function translates integer register file indices into names - std::string getIntRegName(RegIndex); - const int NumIntArchRegs = 32; const int NumIntRegs = (MaxGL + 1) * 8 + NWindows * 16 + NumMicroIntRegs; diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index e06d4b15a..38eba3862 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -42,27 +42,6 @@ using namespace std; class Checkpoint; -//These functions map register indices to names -string SparcISA::getMiscRegName(RegIndex index) -{ - static::string miscRegName[NumMiscRegs] = - {/*"y", "ccr",*/ "asi", "tick", "fprs", "pcr", "pic", - "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr", - "stick", "stick_cmpr", - "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl", - "pil", "cwp", /*"cansave", "canrestore", "cleanwin", "otherwin", - "wstate",*/ "gl", - "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg", - "hstick_cmpr", - "fsr", "prictx", "secctx", "partId", "lsuCtrlReg", - "scratch0", "scratch1", "scratch2", "scratch3", "scratch4", - "scratch5", "scratch6", "scratch7", "cpuMondoHead", "cpuMondoTail", - "devMondoHead", "devMondoTail", "resErrorHead", "resErrorTail", - "nresErrorHead", "nresErrorTail", "TlbData" }; - - return miscRegName[index]; -} - enum RegMask { PSTATE_MASK = (((1 << 4) - 1) << 1) | (((1 << 4) - 1) << 6) | (1 << 12) @@ -328,8 +307,7 @@ MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc) //isn't, instead of panicing. return 0; - panic("Accessing Fullsystem register %s in SE mode\n", - getMiscRegName(miscReg)); + panic("Accessing Fullsystem register %d in SE mode\n", miscReg); #endif } @@ -583,8 +561,8 @@ void MiscRegFile::setReg(int miscReg, //HPSTATE is special because normal trap processing saves HPSTATE when //it goes into a trap, and restores it when it returns. return; - panic("Accessing Fullsystem register %s to %#x in SE mode\n", - getMiscRegName(miscReg), val); + panic("Accessing Fullsystem register %d to %#x in SE mode\n", + miscReg, val); #endif } setRegNoEffect(miscReg, new_val); diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh index 6a010f529..9eff7fcac 100644 --- a/src/arch/sparc/miscregfile.hh +++ b/src/arch/sparc/miscregfile.hh @@ -43,9 +43,6 @@ class Checkpoint; namespace SparcISA { - //These functions map register indices to names - std::string getMiscRegName(RegIndex); - enum MiscRegIndex { /** Ancillary State Registers */ diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index 2389c963d..880d2c3eb 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -35,6 +35,7 @@ #include "sim/system.hh" using namespace SparcISA; +using namespace std; void @@ -61,6 +62,26 @@ MiscRegFile::checkSoftInt(ThreadContext *tc) } } +//These functions map register indices to names +static inline string +getMiscRegName(RegIndex index) +{ + static string miscRegName[NumMiscRegs] = + {/*"y", "ccr",*/ "asi", "tick", "fprs", "pcr", "pic", + "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr", + "stick", "stick_cmpr", + "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl", + "pil", "cwp", /*"cansave", "canrestore", "cleanwin", "otherwin", + "wstate",*/ "gl", + "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg", + "hstick_cmpr", + "fsr", "prictx", "secctx", "partId", "lsuCtrlReg", + "scratch0", "scratch1", "scratch2", "scratch3", "scratch4", + "scratch5", "scratch6", "scratch7", "cpuMondoHead", "cpuMondoTail", + "devMondoHead", "devMondoTail", "resErrorHead", "resErrorTail", + "nresErrorHead", "nresErrorTail", "TlbData" }; + return miscRegName[index]; +} void MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) diff --git a/src/arch/x86/floatregfile.cc b/src/arch/x86/floatregfile.cc index da5372c69..fce7f4868 100644 --- a/src/arch/x86/floatregfile.cc +++ b/src/arch/x86/floatregfile.cc @@ -96,15 +96,6 @@ using namespace std; class Checkpoint; -string X86ISA::getFloatRegName(RegIndex index) -{ - static std::string floatRegName[NumFloatRegs] = - {"mmx0", "mmx1", "mmx2", "mmx3", "mmx4", "mmx5", "mmx6", "mmx7", - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", - "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"}; - return floatRegName[index]; -} - void FloatRegFile::clear() { memset(q, 0, sizeof(FloatReg) * NumFloatRegs); diff --git a/src/arch/x86/floatregfile.hh b/src/arch/x86/floatregfile.hh index b77ddb0eb..ab239dd7d 100644 --- a/src/arch/x86/floatregfile.hh +++ b/src/arch/x86/floatregfile.hh @@ -98,8 +98,6 @@ class Checkpoint; namespace X86ISA { - std::string getFloatRegName(RegIndex); - //Each 128 bit xmm register is broken into two effective 64 bit registers. const int NumFloatRegs = NumMMXRegs + 2 * NumXMMRegs + NumMicroFpRegs; diff --git a/src/arch/x86/intregfile.cc b/src/arch/x86/intregfile.cc index 43cfb8082..58a37cb9e 100644 --- a/src/arch/x86/intregfile.cc +++ b/src/arch/x86/intregfile.cc @@ -97,17 +97,6 @@ using namespace std; class Checkpoint; -string X86ISA::getIntRegName(RegIndex index) -{ - //These might appear to be out of order, but they match - //the encoding for the registers. Who knows why the indexes - //are out of order - static std::string intRegName[NumIntArchRegs] = - {"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}; - return intRegName[index]; -} - int IntRegFile::flattenIndex(int reg) { return reg; diff --git a/src/arch/x86/intregfile.hh b/src/arch/x86/intregfile.hh index b4d256a04..131245352 100644 --- a/src/arch/x86/intregfile.hh +++ b/src/arch/x86/intregfile.hh @@ -100,9 +100,6 @@ namespace X86ISA { class Regfile; - //This function translates integer register file indices into names - std::string getIntRegName(RegIndex); - const int NumIntArchRegs = NUM_INTREGS; const int NumIntRegs = NumIntArchRegs + NumMicroIntRegs + diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc index 01aac14b1..0316603e5 100644 --- a/src/arch/x86/miscregfile.cc +++ b/src/arch/x86/miscregfile.cc @@ -96,12 +96,6 @@ using namespace std; class Checkpoint; -//These functions map register indices to names -string X86ISA::getMiscRegName(RegIndex index) -{ - panic("No misc registers in x86 yet!\n"); -} - void MiscRegFile::clear() { // Blank everything. 0 might not be an appropriate value for some things, diff --git a/src/arch/x86/miscregfile.hh b/src/arch/x86/miscregfile.hh index e59b8d3b1..6d3ae4e92 100644 --- a/src/arch/x86/miscregfile.hh +++ b/src/arch/x86/miscregfile.hh @@ -99,9 +99,6 @@ class Checkpoint; namespace X86ISA { - - std::string getMiscRegName(RegIndex); - //These will have to be updated in the future. const int NumMiscArchRegs = NUM_MISCREGS; const int NumMiscRegs = NUM_MISCREGS; -- cgit v1.2.3 From 7400769768d847b4d7b8f2c27eb78f463c3887a2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 25 Feb 2009 10:22:43 -0800 Subject: X86: Implement IST stack switching. --- src/arch/x86/isa/insts/romutil.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/romutil.py b/src/arch/x86/isa/insts/romutil.py index beeda3d12..e47259eb3 100644 --- a/src/arch/x86/isa/insts/romutil.py +++ b/src/arch/x86/isa/insts/romutil.py @@ -99,7 +99,7 @@ def rom br rom_local_label("%(startLabel)s_stackSwitched") %(startLabel)s_istStackSwitch: - panic "IST based stack switching isn't implemented" + ld t6, tr, [8, t12, t0], 0x1c, dataSize=8, addressSize=8, atCPL0=True br rom_local_label("%(startLabel)s_stackSwitched") %(startLabel)s_cplStackSwitch: -- cgit v1.2.3 From 6fd4bc34a154601ba0a74e41875094c20076e091 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 26 Feb 2009 19:29:17 -0500 Subject: CPA: Add new object for gathering critical path annotations. --- src/arch/alpha/isa/decoder.isa | 59 +++++++++++++++++++++++++++++++++++++++--- src/arch/alpha/isa/main.isa | 1 + 2 files changed, 57 insertions(+), 3 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index 67bc5c7a2..0b2a31410 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -870,9 +870,62 @@ decode OPCODE default Unknown::unknown() { 0x54: m5panic({{ panic("M5 panic instruction called at pc=%#x.", xc->readPC()); }}, IsNonSpeculative); - 0x55: m5reserved1({{ - warn("M5 reserved opcode ignored"); - }}, IsNonSpeculative); +#define CPANN(lbl) CPA::cpa()->lbl(xc->tcBase()) + 0x55: decode RA { + 0x00: m5a_old({{ + panic("Deprecated M5 annotate instruction executed at pc=%#x\n", + xc->readPC()); + }}, IsNonSpeculative); + 0x01: m5a_bsm({{ + CPANN(swSmBegin); + }}, IsNonSpeculative); + 0x02: m5a_esm({{ + CPANN(swSmEnd); + }}, IsNonSpeculative); + 0x03: m5a_begin({{ + CPANN(swExplictBegin); + }}, IsNonSpeculative); + 0x04: m5a_end({{ + CPANN(swEnd); + }}, IsNonSpeculative); + 0x06: m5a_q({{ + CPANN(swQ); + }}, IsNonSpeculative); + 0x07: m5a_dq({{ + CPANN(swDq); + }}, IsNonSpeculative); + 0x08: m5a_wf({{ + CPANN(swWf); + }}, IsNonSpeculative); + 0x09: m5a_we({{ + CPANN(swWe); + }}, IsNonSpeculative); + 0x0C: m5a_sq({{ + CPANN(swSq); + }}, IsNonSpeculative); + 0x0D: m5a_aq({{ + CPANN(swAq); + }}, IsNonSpeculative); + 0x0E: m5a_pq({{ + CPANN(swPq); + }}, IsNonSpeculative); + 0x0F: m5a_l({{ + CPANN(swLink); + }}, IsNonSpeculative); + 0x10: m5a_identify({{ + CPANN(swIdentify); + }}, IsNonSpeculative); + 0x11: m5a_getid({{ + R0 = CPANN(swGetId); + }}, IsNonSpeculative); + 0x13: m5a_scl({{ + CPANN(swSyscallLink); + }}, IsNonSpeculative); + 0x14: m5a_rq({{ + CPANN(swRq); + }}, IsNonSpeculative); + } // M5 Annotate Operations +#undef CPANN 0x56: m5reserved2({{ warn("M5 reserved opcode ignored"); }}, IsNonSpeculative); diff --git a/src/arch/alpha/isa/main.isa b/src/arch/alpha/isa/main.isa index f34bd4b33..aea44976c 100644 --- a/src/arch/alpha/isa/main.isa +++ b/src/arch/alpha/isa/main.isa @@ -68,6 +68,7 @@ using namespace AlphaISA; output exec {{ #include +#include "base/cp_annotate.hh" #include "sim/pseudo_inst.hh" #include "arch/alpha/ipr.hh" #include "base/fenv.hh" -- cgit v1.2.3 From d447ccb2c61a9225e5663ac29c999ac0a52a412f Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Thu, 26 Feb 2009 19:29:17 -0500 Subject: CPA: Add code to automatically record function symbols as CPU executes. --- src/arch/alpha/ev5.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/arch') diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index b3ef8f5d8..02497e282 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -35,6 +35,7 @@ #include "arch/alpha/osfpal.hh" #include "arch/alpha/tlb.hh" #include "arch/alpha/kgdb.h" +#include "base/cp_annotate.hh" #include "base/debug.hh" #include "base/remote_gdb.hh" #include "base/stats/events.hh" @@ -560,6 +561,8 @@ SimpleThread::hwrei() setNextPC(readMiscRegNoEffect(IPR_EXC_ADDR)); + CPA::cpa()->swAutoBegin(tc, readNextPC()); + if (!misspeculating()) { if (kernelStats) kernelStats->hwrei(); -- cgit v1.2.3 From 932f6440a1269c6ceaf2dc07a9ced8ac4b7b1652 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:21:14 -0800 Subject: X86: Add a class to support 32 bit x86 linux process. --- src/arch/x86/linux/process.cc | 23 +-- src/arch/x86/linux/process.hh | 32 +++- src/arch/x86/linux/syscalls.cc | 329 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 362 insertions(+), 22 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/linux/process.cc b/src/arch/x86/linux/process.cc index 8beaf150b..8a3fc67ee 100644 --- a/src/arch/x86/linux/process.cc +++ b/src/arch/x86/linux/process.cc @@ -72,26 +72,17 @@ using namespace X86ISA; SyscallDesc* X86LinuxProcess::getDesc(int callnum) { - if (callnum < 0 || callnum > Num_Syscall_Descs) + if (callnum < 0 || callnum >= Num_Syscall_Descs) return NULL; return &syscallDescs[callnum]; } -X86LinuxProcess::X86LinuxProcess(LiveProcessParams * params, +X86_64LinuxProcess::X86_64LinuxProcess(LiveProcessParams * params, ObjectFile *objFile) - : X86LiveProcess(params, objFile), - Num_Syscall_Descs(273) + : X86LinuxProcess(params, objFile, syscallDescs, 273) {} -void X86LinuxProcess::handleTrap(int trapNum, ThreadContext *tc) -{ - switch(trapNum) - { - //This implementation is from SPARC - case 0x10: //Linux 32 bit syscall trap - tc->syscall(tc->readIntReg(1)); - break; - default: - X86LiveProcess::handleTrap(trapNum, tc); - } -} +I386LinuxProcess::I386LinuxProcess(LiveProcessParams * params, + ObjectFile *objFile) + : X86LinuxProcess(params, objFile, syscallDescs, 324) +{} diff --git a/src/arch/x86/linux/process.hh b/src/arch/x86/linux/process.hh index e224374d4..e80b86537 100644 --- a/src/arch/x86/linux/process.hh +++ b/src/arch/x86/linux/process.hh @@ -67,19 +67,41 @@ namespace X86ISA { /// A process with emulated x86/Linux syscalls. class X86LinuxProcess : public X86LiveProcess +{ + protected: + SyscallDesc *syscallDescs; + + const int Num_Syscall_Descs; + + /// Constructor. + X86LinuxProcess(LiveProcessParams * params, ObjectFile *objFile, + SyscallDesc *_syscallDescs, int numSyscallDescs) : + X86LiveProcess(params, objFile), syscallDescs(_syscallDescs), + Num_Syscall_Descs(numSyscallDescs) + {} + + public: + SyscallDesc* getDesc(int callnum); +}; + +class X86_64LinuxProcess : public X86LinuxProcess { public: /// Constructor. - X86LinuxProcess(LiveProcessParams * params, ObjectFile *objFile); + X86_64LinuxProcess(LiveProcessParams * params, ObjectFile *objFile); /// Array of syscall descriptors, indexed by call number. static SyscallDesc syscallDescs[]; +}; - SyscallDesc* getDesc(int callnum); - - const int Num_Syscall_Descs; +class I386LinuxProcess : public X86LinuxProcess +{ + public: + /// Constructor. + I386LinuxProcess(LiveProcessParams * params, ObjectFile *objFile); - void handleTrap(int trapNum, ThreadContext *tc); + /// Array of syscall descriptors, indexed by call number. + static SyscallDesc syscallDescs[]; }; } // namespace X86ISA diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index ca35a5dd6..324749366 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -122,7 +122,7 @@ archPrctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process, } } -SyscallDesc X86LinuxProcess::syscallDescs[] = { +SyscallDesc X86_64LinuxProcess::syscallDescs[] = { /* 0 */ SyscallDesc("read", readFunc), /* 1 */ SyscallDesc("write", writeFunc), /* 2 */ SyscallDesc("open", openFunc), @@ -397,3 +397,330 @@ SyscallDesc X86LinuxProcess::syscallDescs[] = { /* 271 */ SyscallDesc("ppoll", unimplementedFunc), /* 272 */ SyscallDesc("unshare", unimplementedFunc) }; + +SyscallDesc I386LinuxProcess::syscallDescs[] = { + /* 0 */ SyscallDesc("restart_syscall", unimplementedFunc), + /* 1 */ SyscallDesc("exit", unimplementedFunc), + /* 2 */ SyscallDesc("fork", unimplementedFunc), + /* 3 */ SyscallDesc("read", unimplementedFunc), + /* 4 */ SyscallDesc("write", unimplementedFunc), + /* 5 */ SyscallDesc("open", unimplementedFunc), + /* 6 */ SyscallDesc("close", unimplementedFunc), + /* 7 */ SyscallDesc("waitpid", unimplementedFunc), + /* 8 */ SyscallDesc("creat", unimplementedFunc), + /* 9 */ SyscallDesc("link", unimplementedFunc), + /* 10 */ SyscallDesc("unlink", unimplementedFunc), + /* 11 */ SyscallDesc("execve", unimplementedFunc), + /* 12 */ SyscallDesc("chdir", unimplementedFunc), + /* 13 */ SyscallDesc("time", unimplementedFunc), + /* 14 */ SyscallDesc("mknod", unimplementedFunc), + /* 15 */ SyscallDesc("chmod", unimplementedFunc), + /* 16 */ SyscallDesc("lchown", unimplementedFunc), + /* 17 */ SyscallDesc("break", unimplementedFunc), + /* 18 */ SyscallDesc("oldstat", unimplementedFunc), + /* 19 */ SyscallDesc("lseek", unimplementedFunc), + /* 20 */ SyscallDesc("getpid", unimplementedFunc), + /* 21 */ SyscallDesc("mount", unimplementedFunc), + /* 22 */ SyscallDesc("umount", unimplementedFunc), + /* 23 */ SyscallDesc("setuid", unimplementedFunc), + /* 24 */ SyscallDesc("getuid", unimplementedFunc), + /* 25 */ SyscallDesc("stime", unimplementedFunc), + /* 26 */ SyscallDesc("ptrace", unimplementedFunc), + /* 27 */ SyscallDesc("alarm", unimplementedFunc), + /* 28 */ SyscallDesc("oldfstat", unimplementedFunc), + /* 29 */ SyscallDesc("pause", unimplementedFunc), + /* 30 */ SyscallDesc("utime", unimplementedFunc), + /* 31 */ SyscallDesc("stty", unimplementedFunc), + /* 32 */ SyscallDesc("gtty", unimplementedFunc), + /* 33 */ SyscallDesc("access", unimplementedFunc), + /* 34 */ SyscallDesc("nice", unimplementedFunc), + /* 35 */ SyscallDesc("ftime", unimplementedFunc), + /* 36 */ SyscallDesc("sync", unimplementedFunc), + /* 37 */ SyscallDesc("kill", unimplementedFunc), + /* 38 */ SyscallDesc("rename", unimplementedFunc), + /* 39 */ SyscallDesc("mkdir", unimplementedFunc), + /* 40 */ SyscallDesc("rmdir", unimplementedFunc), + /* 41 */ SyscallDesc("dup", unimplementedFunc), + /* 42 */ SyscallDesc("pipe", unimplementedFunc), + /* 43 */ SyscallDesc("times", unimplementedFunc), + /* 44 */ SyscallDesc("prof", unimplementedFunc), + /* 45 */ SyscallDesc("brk", unimplementedFunc), + /* 46 */ SyscallDesc("setgid", unimplementedFunc), + /* 47 */ SyscallDesc("getgid", unimplementedFunc), + /* 48 */ SyscallDesc("signal", unimplementedFunc), + /* 49 */ SyscallDesc("geteuid", unimplementedFunc), + /* 50 */ SyscallDesc("getegid", unimplementedFunc), + /* 51 */ SyscallDesc("acct", unimplementedFunc), + /* 52 */ SyscallDesc("umount2", unimplementedFunc), + /* 53 */ SyscallDesc("lock", unimplementedFunc), + /* 54 */ SyscallDesc("ioctl", unimplementedFunc), + /* 55 */ SyscallDesc("fcntl", unimplementedFunc), + /* 56 */ SyscallDesc("mpx", unimplementedFunc), + /* 57 */ SyscallDesc("setpgid", unimplementedFunc), + /* 58 */ SyscallDesc("ulimit", unimplementedFunc), + /* 59 */ SyscallDesc("oldolduname", unimplementedFunc), + /* 60 */ SyscallDesc("umask", unimplementedFunc), + /* 61 */ SyscallDesc("chroot", unimplementedFunc), + /* 62 */ SyscallDesc("ustat", unimplementedFunc), + /* 63 */ SyscallDesc("dup2", unimplementedFunc), + /* 64 */ SyscallDesc("getppid", unimplementedFunc), + /* 65 */ SyscallDesc("getpgrp", unimplementedFunc), + /* 66 */ SyscallDesc("setsid", unimplementedFunc), + /* 67 */ SyscallDesc("sigaction", unimplementedFunc), + /* 68 */ SyscallDesc("sgetmask", unimplementedFunc), + /* 69 */ SyscallDesc("ssetmask", unimplementedFunc), + /* 70 */ SyscallDesc("setreuid", unimplementedFunc), + /* 71 */ SyscallDesc("setregid", unimplementedFunc), + /* 72 */ SyscallDesc("sigsuspend", unimplementedFunc), + /* 73 */ SyscallDesc("sigpending", unimplementedFunc), + /* 74 */ SyscallDesc("sethostname", unimplementedFunc), + /* 75 */ SyscallDesc("setrlimit", unimplementedFunc), + /* 76 */ SyscallDesc("getrlimit", unimplementedFunc), + /* 77 */ SyscallDesc("getrusage", unimplementedFunc), + /* 78 */ SyscallDesc("gettimeofday", unimplementedFunc), + /* 79 */ SyscallDesc("settimeofday", unimplementedFunc), + /* 80 */ SyscallDesc("getgroups", unimplementedFunc), + /* 81 */ SyscallDesc("setgroups", unimplementedFunc), + /* 82 */ SyscallDesc("select", unimplementedFunc), + /* 83 */ SyscallDesc("symlink", unimplementedFunc), + /* 84 */ SyscallDesc("oldlstat", unimplementedFunc), + /* 85 */ SyscallDesc("readlink", unimplementedFunc), + /* 86 */ SyscallDesc("uselib", unimplementedFunc), + /* 87 */ SyscallDesc("swapon", unimplementedFunc), + /* 88 */ SyscallDesc("reboot", unimplementedFunc), + /* 89 */ SyscallDesc("readdir", unimplementedFunc), + /* 90 */ SyscallDesc("mmap", unimplementedFunc), + /* 91 */ SyscallDesc("munmap", unimplementedFunc), + /* 92 */ SyscallDesc("truncate", unimplementedFunc), + /* 93 */ SyscallDesc("ftruncate", unimplementedFunc), + /* 94 */ SyscallDesc("fchmod", unimplementedFunc), + /* 95 */ SyscallDesc("fchown", unimplementedFunc), + /* 96 */ SyscallDesc("getpriority", unimplementedFunc), + /* 97 */ SyscallDesc("setpriority", unimplementedFunc), + /* 98 */ SyscallDesc("profil", unimplementedFunc), + /* 99 */ SyscallDesc("statfs", unimplementedFunc), + /* 100 */ SyscallDesc("fstatfs", unimplementedFunc), + /* 101 */ SyscallDesc("ioperm", unimplementedFunc), + /* 102 */ SyscallDesc("socketcall", unimplementedFunc), + /* 103 */ SyscallDesc("syslog", unimplementedFunc), + /* 104 */ SyscallDesc("setitimer", unimplementedFunc), + /* 105 */ SyscallDesc("getitimer", unimplementedFunc), + /* 106 */ SyscallDesc("stat", unimplementedFunc), + /* 107 */ SyscallDesc("lstat", unimplementedFunc), + /* 108 */ SyscallDesc("fstat", unimplementedFunc), + /* 109 */ SyscallDesc("olduname", unimplementedFunc), + /* 110 */ SyscallDesc("iopl", unimplementedFunc), + /* 111 */ SyscallDesc("vhangup", unimplementedFunc), + /* 112 */ SyscallDesc("idle", unimplementedFunc), + /* 113 */ SyscallDesc("vm86old", unimplementedFunc), + /* 114 */ SyscallDesc("wait4", unimplementedFunc), + /* 115 */ SyscallDesc("swapoff", unimplementedFunc), + /* 116 */ SyscallDesc("sysinfo", unimplementedFunc), + /* 117 */ SyscallDesc("ipc", unimplementedFunc), + /* 118 */ SyscallDesc("fsync", unimplementedFunc), + /* 119 */ SyscallDesc("sigreturn", unimplementedFunc), + /* 120 */ SyscallDesc("clone", unimplementedFunc), + /* 121 */ SyscallDesc("setdomainname", unimplementedFunc), + /* 122 */ SyscallDesc("uname", unimplementedFunc), + /* 123 */ SyscallDesc("modify_ldt", unimplementedFunc), + /* 124 */ SyscallDesc("adjtimex", unimplementedFunc), + /* 125 */ SyscallDesc("mprotect", unimplementedFunc), + /* 126 */ SyscallDesc("sigprocmask", unimplementedFunc), + /* 127 */ SyscallDesc("create_module", unimplementedFunc), + /* 128 */ SyscallDesc("init_module", unimplementedFunc), + /* 129 */ SyscallDesc("delete_module", unimplementedFunc), + /* 130 */ SyscallDesc("get_kernel_syms", unimplementedFunc), + /* 131 */ SyscallDesc("quotactl", unimplementedFunc), + /* 132 */ SyscallDesc("getpgid", unimplementedFunc), + /* 133 */ SyscallDesc("fchdir", unimplementedFunc), + /* 134 */ SyscallDesc("bdflush", unimplementedFunc), + /* 135 */ SyscallDesc("sysfs", unimplementedFunc), + /* 136 */ SyscallDesc("personality", unimplementedFunc), + /* 137 */ SyscallDesc("afs_syscall", unimplementedFunc), + /* 138 */ SyscallDesc("setfsuid", unimplementedFunc), + /* 139 */ SyscallDesc("setfsgid", unimplementedFunc), + /* 140 */ SyscallDesc("_llseek", unimplementedFunc), + /* 141 */ SyscallDesc("getdents", unimplementedFunc), + /* 142 */ SyscallDesc("_newselect", unimplementedFunc), + /* 143 */ SyscallDesc("flock", unimplementedFunc), + /* 144 */ SyscallDesc("msync", unimplementedFunc), + /* 145 */ SyscallDesc("readv", unimplementedFunc), + /* 146 */ SyscallDesc("writev", unimplementedFunc), + /* 147 */ SyscallDesc("getsid", unimplementedFunc), + /* 148 */ SyscallDesc("fdatasync", unimplementedFunc), + /* 149 */ SyscallDesc("_sysctl", unimplementedFunc), + /* 150 */ SyscallDesc("mlock", unimplementedFunc), + /* 151 */ SyscallDesc("munlock", unimplementedFunc), + /* 152 */ SyscallDesc("mlockall", unimplementedFunc), + /* 153 */ SyscallDesc("munlockall", unimplementedFunc), + /* 154 */ SyscallDesc("sched_setparam", unimplementedFunc), + /* 155 */ SyscallDesc("sched_getparam", unimplementedFunc), + /* 156 */ SyscallDesc("sched_setscheduler", unimplementedFunc), + /* 157 */ SyscallDesc("sched_getscheduler", unimplementedFunc), + /* 158 */ SyscallDesc("sched_yield", unimplementedFunc), + /* 159 */ SyscallDesc("sched_get_priority_max", unimplementedFunc), + /* 160 */ SyscallDesc("sched_get_priority_min", unimplementedFunc), + /* 161 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc), + /* 162 */ SyscallDesc("nanosleep", unimplementedFunc), + /* 163 */ SyscallDesc("mremap", unimplementedFunc), + /* 164 */ SyscallDesc("setresuid", unimplementedFunc), + /* 165 */ SyscallDesc("getresuid", unimplementedFunc), + /* 166 */ SyscallDesc("vm86", unimplementedFunc), + /* 167 */ SyscallDesc("query_module", unimplementedFunc), + /* 168 */ SyscallDesc("poll", unimplementedFunc), + /* 169 */ SyscallDesc("nfsservctl", unimplementedFunc), + /* 170 */ SyscallDesc("setresgid", unimplementedFunc), + /* 171 */ SyscallDesc("getresgid", unimplementedFunc), + /* 172 */ SyscallDesc("prctl", unimplementedFunc), + /* 173 */ SyscallDesc("rt_sigreturn", unimplementedFunc), + /* 174 */ SyscallDesc("rt_sigaction", unimplementedFunc), + /* 175 */ SyscallDesc("rt_sigprocmask", unimplementedFunc), + /* 176 */ SyscallDesc("rt_sigpending", unimplementedFunc), + /* 177 */ SyscallDesc("rt_sigtimedwait", unimplementedFunc), + /* 178 */ SyscallDesc("rt_sigqueueinfo", unimplementedFunc), + /* 179 */ SyscallDesc("rt_sigsuspend", unimplementedFunc), + /* 180 */ SyscallDesc("pread64", unimplementedFunc), + /* 181 */ SyscallDesc("pwrite64", unimplementedFunc), + /* 182 */ SyscallDesc("chown", unimplementedFunc), + /* 183 */ SyscallDesc("getcwd", unimplementedFunc), + /* 184 */ SyscallDesc("capget", unimplementedFunc), + /* 185 */ SyscallDesc("capset", unimplementedFunc), + /* 186 */ SyscallDesc("sigaltstack", unimplementedFunc), + /* 187 */ SyscallDesc("sendfile", unimplementedFunc), + /* 188 */ SyscallDesc("getpmsg", unimplementedFunc), + /* 189 */ SyscallDesc("putpmsg", unimplementedFunc), + /* 190 */ SyscallDesc("vfork", unimplementedFunc), + /* 191 */ SyscallDesc("ugetrlimit", unimplementedFunc), + /* 192 */ SyscallDesc("mmap2", unimplementedFunc), + /* 193 */ SyscallDesc("truncate64", unimplementedFunc), + /* 194 */ SyscallDesc("ftruncate64", unimplementedFunc), + /* 195 */ SyscallDesc("stat64", unimplementedFunc), + /* 196 */ SyscallDesc("lstat64", unimplementedFunc), + /* 197 */ SyscallDesc("fstat64", unimplementedFunc), + /* 198 */ SyscallDesc("lchown32", unimplementedFunc), + /* 199 */ SyscallDesc("getuid32", unimplementedFunc), + /* 200 */ SyscallDesc("getgid32", unimplementedFunc), + /* 201 */ SyscallDesc("geteuid32", unimplementedFunc), + /* 202 */ SyscallDesc("getegid32", unimplementedFunc), + /* 203 */ SyscallDesc("setreuid32", unimplementedFunc), + /* 204 */ SyscallDesc("setregid32", unimplementedFunc), + /* 205 */ SyscallDesc("getgroups32", unimplementedFunc), + /* 206 */ SyscallDesc("setgroups32", unimplementedFunc), + /* 207 */ SyscallDesc("fchown32", unimplementedFunc), + /* 208 */ SyscallDesc("setresuid32", unimplementedFunc), + /* 209 */ SyscallDesc("getresuid32", unimplementedFunc), + /* 210 */ SyscallDesc("setresgid32", unimplementedFunc), + /* 211 */ SyscallDesc("getresgid32", unimplementedFunc), + /* 212 */ SyscallDesc("chown32", unimplementedFunc), + /* 213 */ SyscallDesc("setuid32", unimplementedFunc), + /* 214 */ SyscallDesc("setgid32", unimplementedFunc), + /* 215 */ SyscallDesc("setfsuid32", unimplementedFunc), + /* 216 */ SyscallDesc("setfsgid32", unimplementedFunc), + /* 217 */ SyscallDesc("pivot_root", unimplementedFunc), + /* 218 */ SyscallDesc("mincore", unimplementedFunc), + /* 219 */ SyscallDesc("madvise", unimplementedFunc), + /* 220 */ SyscallDesc("madvise1", unimplementedFunc), + /* 221 */ SyscallDesc("getdents64", unimplementedFunc), + /* 222 */ SyscallDesc("fcntl64", unimplementedFunc), + /* 223 */ SyscallDesc("unused", unimplementedFunc), + /* 224 */ SyscallDesc("gettid", unimplementedFunc), + /* 225 */ SyscallDesc("readahead", unimplementedFunc), + /* 226 */ SyscallDesc("setxattr", unimplementedFunc), + /* 227 */ SyscallDesc("lsetxattr", unimplementedFunc), + /* 228 */ SyscallDesc("fsetxattr", unimplementedFunc), + /* 229 */ SyscallDesc("getxattr", unimplementedFunc), + /* 230 */ SyscallDesc("lgetxattr", unimplementedFunc), + /* 231 */ SyscallDesc("fgetxattr", unimplementedFunc), + /* 232 */ SyscallDesc("listxattr", unimplementedFunc), + /* 233 */ SyscallDesc("llistxattr", unimplementedFunc), + /* 234 */ SyscallDesc("flistxattr", unimplementedFunc), + /* 235 */ SyscallDesc("removexattr", unimplementedFunc), + /* 236 */ SyscallDesc("lremovexattr", unimplementedFunc), + /* 237 */ SyscallDesc("fremovexattr", unimplementedFunc), + /* 238 */ SyscallDesc("tkill", unimplementedFunc), + /* 239 */ SyscallDesc("sendfile64", unimplementedFunc), + /* 240 */ SyscallDesc("futex", unimplementedFunc), + /* 241 */ SyscallDesc("sched_setaffinity", unimplementedFunc), + /* 242 */ SyscallDesc("sched_getaffinity", unimplementedFunc), + /* 243 */ SyscallDesc("set_thread_area", unimplementedFunc), + /* 244 */ SyscallDesc("get_thread_area", unimplementedFunc), + /* 245 */ SyscallDesc("io_setup", unimplementedFunc), + /* 246 */ SyscallDesc("io_destroy", unimplementedFunc), + /* 247 */ SyscallDesc("io_getevents", unimplementedFunc), + /* 248 */ SyscallDesc("io_submit", unimplementedFunc), + /* 249 */ SyscallDesc("io_cancel", unimplementedFunc), + /* 250 */ SyscallDesc("fadvise64", unimplementedFunc), + /* 251 */ SyscallDesc("unused", unimplementedFunc), + /* 252 */ SyscallDesc("exit_group", unimplementedFunc), + /* 253 */ SyscallDesc("lookup_dcookie", unimplementedFunc), + /* 254 */ SyscallDesc("epoll_create", unimplementedFunc), + /* 255 */ SyscallDesc("epoll_ctl", unimplementedFunc), + /* 256 */ SyscallDesc("epoll_wait", unimplementedFunc), + /* 257 */ SyscallDesc("remap_file_pages", unimplementedFunc), + /* 258 */ SyscallDesc("set_tid_address", unimplementedFunc), + /* 259 */ SyscallDesc("timer_create", unimplementedFunc), + /* 260 */ SyscallDesc("timer_settime", unimplementedFunc), + /* 261 */ SyscallDesc("timer_gettime", unimplementedFunc), + /* 262 */ SyscallDesc("timer_getoverrun", unimplementedFunc), + /* 263 */ SyscallDesc("timer_delete", unimplementedFunc), + /* 264 */ SyscallDesc("clock_settime", unimplementedFunc), + /* 265 */ SyscallDesc("clock_gettime", unimplementedFunc), + /* 266 */ SyscallDesc("clock_getres", unimplementedFunc), + /* 267 */ SyscallDesc("clock_nanosleep", unimplementedFunc), + /* 268 */ SyscallDesc("statfs64", unimplementedFunc), + /* 269 */ SyscallDesc("fstatfs64", unimplementedFunc), + /* 270 */ SyscallDesc("tgkill", unimplementedFunc), + /* 271 */ SyscallDesc("utimes", unimplementedFunc), + /* 272 */ SyscallDesc("fadvise64_64", unimplementedFunc), + /* 273 */ SyscallDesc("vserver", unimplementedFunc), + /* 274 */ SyscallDesc("mbind", unimplementedFunc), + /* 275 */ SyscallDesc("get_mempolicy", unimplementedFunc), + /* 276 */ SyscallDesc("set_mempolicy", unimplementedFunc), + /* 277 */ SyscallDesc("mq_open", unimplementedFunc), + /* 278 */ SyscallDesc("mq_unlink", unimplementedFunc), + /* 279 */ SyscallDesc("mq_timedsend", unimplementedFunc), + /* 280 */ SyscallDesc("mq_timedreceive", unimplementedFunc), + /* 281 */ SyscallDesc("mq_notify", unimplementedFunc), + /* 282 */ SyscallDesc("mq_getsetattr", unimplementedFunc), + /* 283 */ SyscallDesc("kexec_load", unimplementedFunc), + /* 284 */ SyscallDesc("waitid", unimplementedFunc), + /* 285 */ SyscallDesc("sys_setaltroot", unimplementedFunc), + /* 286 */ SyscallDesc("add_key", unimplementedFunc), + /* 287 */ SyscallDesc("request_key", unimplementedFunc), + /* 288 */ SyscallDesc("keyctl", unimplementedFunc), + /* 289 */ SyscallDesc("ioprio_set", unimplementedFunc), + /* 290 */ SyscallDesc("ioprio_get", unimplementedFunc), + /* 291 */ SyscallDesc("inotify_init", unimplementedFunc), + /* 292 */ SyscallDesc("inotify_add_watch", unimplementedFunc), + /* 293 */ SyscallDesc("inotify_rm_watch", unimplementedFunc), + /* 294 */ SyscallDesc("migrate_pages", unimplementedFunc), + /* 295 */ SyscallDesc("openat", unimplementedFunc), + /* 296 */ SyscallDesc("mkdirat", unimplementedFunc), + /* 297 */ SyscallDesc("mknodat", unimplementedFunc), + /* 298 */ SyscallDesc("fchownat", unimplementedFunc), + /* 299 */ SyscallDesc("futimesat", unimplementedFunc), + /* 300 */ SyscallDesc("fstatat64", unimplementedFunc), + /* 301 */ SyscallDesc("unlinkat", unimplementedFunc), + /* 302 */ SyscallDesc("renameat", unimplementedFunc), + /* 303 */ SyscallDesc("linkat", unimplementedFunc), + /* 304 */ SyscallDesc("symlinkat", unimplementedFunc), + /* 305 */ SyscallDesc("readlinkat", unimplementedFunc), + /* 306 */ SyscallDesc("fchmodat", unimplementedFunc), + /* 307 */ SyscallDesc("faccessat", unimplementedFunc), + /* 308 */ SyscallDesc("pselect6", unimplementedFunc), + /* 309 */ SyscallDesc("ppoll", unimplementedFunc), + /* 310 */ SyscallDesc("unshare", unimplementedFunc), + /* 311 */ SyscallDesc("set_robust_list", unimplementedFunc), + /* 312 */ SyscallDesc("get_robust_list", unimplementedFunc), + /* 313 */ SyscallDesc("splice", unimplementedFunc), + /* 314 */ SyscallDesc("sync_file_range", unimplementedFunc), + /* 315 */ SyscallDesc("tee", unimplementedFunc), + /* 316 */ SyscallDesc("vmsplice", unimplementedFunc), + /* 317 */ SyscallDesc("move_pages", unimplementedFunc), + /* 318 */ SyscallDesc("getcpu", unimplementedFunc), + /* 319 */ SyscallDesc("epoll_pwait", unimplementedFunc), + /* 320 */ SyscallDesc("utimensat", unimplementedFunc), + /* 321 */ SyscallDesc("signalfd", unimplementedFunc), + /* 322 */ SyscallDesc("timerfd", unimplementedFunc), + /* 323 */ SyscallDesc("eventfd", unimplementedFunc) +}; -- cgit v1.2.3 From 05de9f4e2cb0771a8f83dc1888c877852e19f1ad Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:21:36 -0800 Subject: X86: Distinguish the width of values on the stack between 32 and 64 bit processes. --- src/arch/x86/linux/process.cc | 13 +--- src/arch/x86/linux/process.hh | 31 ++------ src/arch/x86/process.cc | 164 ++++++++++++++++++++++++++++++++++-------- src/arch/x86/process.hh | 33 +++++++-- 4 files changed, 172 insertions(+), 69 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/linux/process.cc b/src/arch/x86/linux/process.cc index 8a3fc67ee..da22d9851 100644 --- a/src/arch/x86/linux/process.cc +++ b/src/arch/x86/linux/process.cc @@ -64,25 +64,16 @@ #include "kern/linux/linux.hh" #include "sim/process.hh" -#include "sim/syscall_emul.hh" using namespace std; using namespace X86ISA; -SyscallDesc* -X86LinuxProcess::getDesc(int callnum) -{ - if (callnum < 0 || callnum >= Num_Syscall_Descs) - return NULL; - return &syscallDescs[callnum]; -} - X86_64LinuxProcess::X86_64LinuxProcess(LiveProcessParams * params, ObjectFile *objFile) - : X86LinuxProcess(params, objFile, syscallDescs, 273) + : X86_64LiveProcess(params, objFile, syscallDescs, 273) {} I386LinuxProcess::I386LinuxProcess(LiveProcessParams * params, ObjectFile *objFile) - : X86LinuxProcess(params, objFile, syscallDescs, 324) + : I386LiveProcess(params, objFile, syscallDescs, 324) {} diff --git a/src/arch/x86/linux/process.hh b/src/arch/x86/linux/process.hh index e80b86537..2f37692e3 100644 --- a/src/arch/x86/linux/process.hh +++ b/src/arch/x86/linux/process.hh @@ -65,43 +65,26 @@ namespace X86ISA { -/// A process with emulated x86/Linux syscalls. -class X86LinuxProcess : public X86LiveProcess +class X86_64LinuxProcess : public X86_64LiveProcess { protected: - SyscallDesc *syscallDescs; - - const int Num_Syscall_Descs; - - /// Constructor. - X86LinuxProcess(LiveProcessParams * params, ObjectFile *objFile, - SyscallDesc *_syscallDescs, int numSyscallDescs) : - X86LiveProcess(params, objFile), syscallDescs(_syscallDescs), - Num_Syscall_Descs(numSyscallDescs) - {} - - public: - SyscallDesc* getDesc(int callnum); -}; + /// Array of syscall descriptors, indexed by call number. + static SyscallDesc syscallDescs[]; -class X86_64LinuxProcess : public X86LinuxProcess -{ public: /// Constructor. X86_64LinuxProcess(LiveProcessParams * params, ObjectFile *objFile); +}; +class I386LinuxProcess : public I386LiveProcess +{ + protected: /// Array of syscall descriptors, indexed by call number. static SyscallDesc syscallDescs[]; -}; -class I386LinuxProcess : public X86LinuxProcess -{ public: /// Constructor. I386LinuxProcess(LiveProcessParams * params, ObjectFile *objFile); - - /// Array of syscall descriptors, indexed by call number. - static SyscallDesc syscallDescs[]; }; } // namespace X86ISA diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index d6f3b2371..800dd44ef 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -98,48 +98,72 @@ #include "mem/page_table.hh" #include "mem/translating_port.hh" #include "sim/process_impl.hh" +#include "sim/syscall_emul.hh" #include "sim/system.hh" using namespace std; using namespace X86ISA; -X86LiveProcess::X86LiveProcess(LiveProcessParams * params, - ObjectFile *objFile) - : LiveProcess(params, objFile) +X86LiveProcess::X86LiveProcess(LiveProcessParams * params, ObjectFile *objFile, + SyscallDesc *_syscallDescs, int _numSyscallDescs) : + LiveProcess(params, objFile), syscallDescs(_syscallDescs), + numSyscallDescs(_numSyscallDescs) { brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize(); brk_point = roundUp(brk_point, VMPageSize); +} - // Set pointer for next thread stack. Reserve 8M for main stack. - next_thread_stack_base = stack_base - (8 * 1024 * 1024); - +X86_64LiveProcess::X86_64LiveProcess(LiveProcessParams *params, + ObjectFile *objFile, SyscallDesc *_syscallDescs, + int _numSyscallDescs) : + X86LiveProcess(params, objFile, _syscallDescs, _numSyscallDescs) +{ // Set up stack. On X86_64 Linux, stack goes from the top of memory // downward, less the hole for the kernel address space plus one page // for undertermined purposes. stack_base = (Addr)0x7FFFFFFFF000ULL; + // Set pointer for next thread stack. Reserve 8M for main stack. + next_thread_stack_base = stack_base - (8 * 1024 * 1024); + // Set up region for mmaps. This was determined empirically and may not // always be correct. mmap_start = mmap_end = (Addr)0x2aaaaaaab000ULL; } -void X86LiveProcess::handleTrap(int trapNum, ThreadContext *tc) +I386LiveProcess::I386LiveProcess(LiveProcessParams *params, + ObjectFile *objFile, SyscallDesc *_syscallDescs, + int _numSyscallDescs) : + X86LiveProcess(params, objFile, _syscallDescs, _numSyscallDescs) { - switch(trapNum) - { - default: - panic("Unimplemented trap to operating system: trap number %#x.\n", trapNum); - } + stack_base = (Addr)0xffffe000ULL; + + // Set pointer for next thread stack. Reserve 8M for main stack. + next_thread_stack_base = stack_base - (8 * 1024 * 1024); + + // Set up region for mmaps. This was determined empirically and may not + // always be correct. + mmap_start = mmap_end = (Addr)0xf7ffd000ULL; +} + +SyscallDesc* +X86LiveProcess::getDesc(int callnum) +{ + if (callnum < 0 || callnum >= numSyscallDescs) + return NULL; + return &syscallDescs[callnum]; } void -X86LiveProcess::startup() +X86_64LiveProcess::startup() { + LiveProcess::startup(); + if (checkpointRestored) return; - argsInit(sizeof(IntReg), VMPageSize); + argsInit(sizeof(uint64_t), VMPageSize); for (int i = 0; i < contextIds.size(); i++) { ThreadContext * tc = system->getThreadContext(contextIds[i]); @@ -198,12 +222,80 @@ X86LiveProcess::startup() } void -X86LiveProcess::argsInit(int intSize, int pageSize) +I386LiveProcess::startup() { - typedef AuxVector auxv_t; - std::vector auxv; + LiveProcess::startup(); + + if (checkpointRestored) + return; + + argsInit(sizeof(uint32_t), VMPageSize); + + for (int i = 0; i < contextIds.size(); i++) { + ThreadContext * tc = system->getThreadContext(contextIds[i]); + + SegAttr dataAttr = 0; + dataAttr.writable = 1; + dataAttr.readable = 1; + dataAttr.expandDown = 0; + dataAttr.dpl = 3; + dataAttr.defaultSize = 1; + dataAttr.longMode = 0; + + //Initialize the segment registers. + for(int seg = 0; seg < NUM_SEGMENTREGS; seg++) { + tc->setMiscRegNoEffect(MISCREG_SEG_BASE(seg), 0); + tc->setMiscRegNoEffect(MISCREG_SEG_EFF_BASE(seg), 0); + tc->setMiscRegNoEffect(MISCREG_SEG_ATTR(seg), dataAttr); + tc->setMiscRegNoEffect(MISCREG_SEG_SEL(seg), 0xB); + } + + SegAttr csAttr = 0; + csAttr.writable = 0; + csAttr.readable = 1; + csAttr.expandDown = 0; + csAttr.dpl = 3; + csAttr.defaultSize = 1; + csAttr.longMode = 0; + + tc->setMiscRegNoEffect(MISCREG_CS_ATTR, csAttr); + + //Set up the registers that describe the operating mode. + CR0 cr0 = 0; + cr0.pg = 1; // Turn on paging. + cr0.cd = 0; // Don't disable caching. + cr0.nw = 0; // This is bit is defined to be ignored. + cr0.am = 0; // No alignment checking + cr0.wp = 0; // Supervisor mode can write read only pages + cr0.ne = 1; + cr0.et = 1; // This should always be 1 + cr0.ts = 0; // We don't do task switching, so causing fp exceptions + // would be pointless. + cr0.em = 0; // Allow x87 instructions to execute natively. + cr0.mp = 1; // This doesn't really matter, but the manual suggests + // setting it to one. + cr0.pe = 1; // We're definitely in protected mode. + tc->setMiscReg(MISCREG_CR0, cr0); - Process::startup(); + Efer efer = 0; + efer.sce = 1; // Enable system call extensions. + efer.lme = 1; // Enable long mode. + efer.lma = 0; // Deactivate long mode. + efer.nxe = 1; // Enable nx support. + efer.svme = 0; // Disable svm support for now. It isn't implemented. + efer.ffxsr = 1; // Turn on fast fxsave and fxrstor. + tc->setMiscReg(MISCREG_EFER, efer); + } +} + +template +void +X86LiveProcess::argsInit(int pageSize) +{ + int intSize = sizeof(IntType); + + typedef AuxVector auxv_t; + std::vector auxv; string filename; if(argv.size() < 1) @@ -396,15 +488,15 @@ X86LiveProcess::argsInit(int intSize, int pageSize) roundUp(stack_size, pageSize)); // map out initial stack contents - Addr sentry_base = stack_base - sentry_size; - Addr file_name_base = sentry_base - file_name_size; - Addr env_data_base = file_name_base - env_data_size; - Addr arg_data_base = env_data_base - arg_data_size; - Addr aux_data_base = arg_data_base - info_block_padding - aux_data_size; - Addr auxv_array_base = aux_data_base - aux_array_size - aux_padding; - Addr envp_array_base = auxv_array_base - envp_array_size; - Addr argv_array_base = envp_array_base - argv_array_size; - Addr argc_base = argv_array_base - argc_size; + IntType sentry_base = stack_base - sentry_size; + IntType file_name_base = sentry_base - file_name_size; + IntType env_data_base = file_name_base - env_data_size; + IntType arg_data_base = env_data_base - arg_data_size; + IntType aux_data_base = arg_data_base - info_block_padding - aux_data_size; + IntType auxv_array_base = aux_data_base - aux_array_size - aux_padding; + IntType envp_array_base = auxv_array_base - envp_array_size; + IntType argv_array_base = envp_array_base - argv_array_size; + IntType argc_base = argv_array_base - argc_size; DPRINTF(Stack, "The addresses of items on the initial stack:\n"); DPRINTF(Stack, "0x%x - file name\n", file_name_base); @@ -420,11 +512,11 @@ X86LiveProcess::argsInit(int intSize, int pageSize) // write contents to stack // figure out argc - uint64_t argc = argv.size(); - uint64_t guestArgc = X86ISA::htog(argc); + IntType argc = argv.size(); + IntType guestArgc = X86ISA::htog(argc); //Write out the sentry void * - uint64_t sentry_NULL = 0; + IntType sentry_NULL = 0; initVirtMem->writeBlob(sentry_base, (uint8_t*)&sentry_NULL, sentry_size); @@ -470,3 +562,15 @@ X86LiveProcess::argsInit(int intSize, int pageSize) // num_processes++; } + +void +X86_64LiveProcess::argsInit(int intSize, int pageSize) +{ + X86LiveProcess::argsInit(pageSize); +} + +void +I386LiveProcess::argsInit(int intSize, int pageSize) +{ + X86LiveProcess::argsInit(pageSize); +} diff --git a/src/arch/x86/process.hh b/src/arch/x86/process.hh index d034d990e..8d77bd79d 100644 --- a/src/arch/x86/process.hh +++ b/src/arch/x86/process.hh @@ -62,22 +62,47 @@ #include #include "sim/process.hh" +class SyscallDesc; + namespace X86ISA { class X86LiveProcess : public LiveProcess { protected: - X86LiveProcess(LiveProcessParams * params, ObjectFile *objFile); + SyscallDesc *syscallDescs; + const int numSyscallDescs; - void startup(); + X86LiveProcess(LiveProcessParams * params, ObjectFile *objFile, + SyscallDesc *_syscallDescs, int _numSyscallDescs); + + template + void argsInit(int pageSize); + + public: + SyscallDesc* getDesc(int callnum); + }; + + class X86_64LiveProcess : public X86LiveProcess + { + protected: + X86_64LiveProcess(LiveProcessParams *params, ObjectFile *objFile, + SyscallDesc *_syscallDescs, int _numSyscallDescs); public: + void argsInit(int intSize, int pageSize); + void startup(); + }; - //Handles traps which request services from the operating system - virtual void handleTrap(int trapNum, ThreadContext *tc); + class I386LiveProcess : public X86LiveProcess + { + protected: + I386LiveProcess(LiveProcessParams *params, ObjectFile *objFile, + SyscallDesc *_syscallDescs, int _numSyscallDescs); + public: void argsInit(int intSize, int pageSize); + void startup(); }; } -- cgit v1.2.3 From 60aab03e854c0d955127d12c63f4c99a36d19d80 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:21:58 -0800 Subject: X86: Implement the int system call interface in the decoder. --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa index 005864f02..817986232 100644 --- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa @@ -418,7 +418,18 @@ default: Inst::RET_FAR(); } 0x4: int3(); +#if FULL_SYSTEM 0x5: int_Ib(); +#else + // Really only the LSB matters, but the predecoder will sign + // extend it, and there's no easy way to specify only checking + // the first byte. + 0x5: decode IMMEDIATE { + 0xffffffffffffff80: + SyscallInst::int80('xc->syscall(Rax)', IsSyscall); + default: int_Ib(); + } +#endif 0x6: decode MODE_SUBMODE { 0x0: Inst::UD2(); default: into(); -- cgit v1.2.3 From 9a000c51736d97c1109be296ea7d1fd41d84debb Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:22:14 -0800 Subject: Processes: Make getting and setting system call arguments part of a process object. --- src/arch/SConscript | 1 - src/arch/alpha/freebsd/system.cc | 5 ++- src/arch/alpha/isa_traits.hh | 9 ++--- src/arch/alpha/linux/process.cc | 14 ++++---- src/arch/alpha/process.cc | 40 ++++++++++++++++++--- src/arch/alpha/process.hh | 5 +++ src/arch/alpha/syscallreturn.hh | 59 ------------------------------- src/arch/alpha/tru64/process.cc | 35 +++++++++--------- src/arch/alpha/utility.cc | 5 +-- src/arch/mips/isa_traits.hh | 14 +------- src/arch/mips/linux/process.cc | 14 ++++---- src/arch/mips/process.cc | 34 ++++++++++++++++++ src/arch/mips/process.hh | 4 +++ src/arch/mips/syscallreturn.hh | 55 ----------------------------- src/arch/sparc/isa_traits.hh | 8 ++--- src/arch/sparc/linux/process.hh | 1 - src/arch/sparc/linux/syscalls.cc | 9 +++-- src/arch/sparc/process.cc | 63 +++++++++++++++++++++++++++++++++ src/arch/sparc/process.hh | 7 ++++ src/arch/sparc/solaris/process.cc | 2 +- src/arch/sparc/syscallreturn.hh | 74 --------------------------------------- src/arch/sparc/utility.cc | 3 +- src/arch/x86/isa_traits.hh | 12 ------- src/arch/x86/linux/process.hh | 1 - src/arch/x86/linux/syscalls.cc | 6 ++-- src/arch/x86/process.cc | 44 +++++++++++++++++++++++ src/arch/x86/process.hh | 8 +++++ src/arch/x86/syscallreturn.hh | 74 --------------------------------------- 28 files changed, 254 insertions(+), 352 deletions(-) delete mode 100644 src/arch/alpha/syscallreturn.hh delete mode 100644 src/arch/mips/syscallreturn.hh delete mode 100644 src/arch/sparc/syscallreturn.hh delete mode 100644 src/arch/x86/syscallreturn.hh (limited to 'src/arch') diff --git a/src/arch/SConscript b/src/arch/SConscript index 2b0af2816..b85ffbd89 100644 --- a/src/arch/SConscript +++ b/src/arch/SConscript @@ -56,7 +56,6 @@ isa_switch_hdrs = Split(''' regfile.hh remote_gdb.hh stacktrace.hh - syscallreturn.hh tlb.hh types.hh utility.hh diff --git a/src/arch/alpha/freebsd/system.cc b/src/arch/alpha/freebsd/system.cc index f2ea1b587..e541b260c 100644 --- a/src/arch/alpha/freebsd/system.cc +++ b/src/arch/alpha/freebsd/system.cc @@ -74,9 +74,8 @@ FreebsdAlphaSystem::doCalibrateClocks(ThreadContext *tc) Addr ppc_vaddr = 0; Addr timer_vaddr = 0; - assert(NumArgumentRegs >= 3); - ppc_vaddr = (Addr)tc->readIntReg(ArgumentReg[1]); - timer_vaddr = (Addr)tc->readIntReg(ArgumentReg[2]); + ppc_vaddr = (Addr)tc->readIntReg(17); + timer_vaddr = (Addr)tc->readIntReg(18); virtPort.write(ppc_vaddr, (uint32_t)Clock::Frequency); virtPort.write(timer_vaddr, (uint32_t)TIMER_FREQUENCY); diff --git a/src/arch/alpha/isa_traits.hh b/src/arch/alpha/isa_traits.hh index e5e4542a7..d37a769ea 100644 --- a/src/arch/alpha/isa_traits.hh +++ b/src/arch/alpha/isa_traits.hh @@ -152,12 +152,9 @@ const int ReturnAddressReg = 26; const int ReturnValueReg = 0; const int FramePointerReg = 15; -const int ArgumentReg[] = {16, 17, 18, 19, 20, 21}; -const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int); - -const int SyscallNumReg = ReturnValueReg; -const int SyscallPseudoReturnReg = ArgumentReg[4]; -const int SyscallSuccessReg = 19; +const int SyscallNumReg = 0; +const int FirstArgumentReg = 16; +const int SyscallPseudoReturnReg = 20; const int LogVMPageSize = 13; // 8K bytes const int VMPageSize = (1 << LogVMPageSize); diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc index 605e40627..1e4f75790 100644 --- a/src/arch/alpha/linux/process.cc +++ b/src/arch/alpha/linux/process.cc @@ -48,7 +48,7 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg name(tc->getSyscallArg(0)); + TypedBufferArg name(process->getSyscallArg(tc, 0)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -67,13 +67,13 @@ static SyscallReturn osf_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = tc->getSyscallArg(0); - // unsigned nbytes = tc->getSyscallArg(2); + unsigned op = process->getSyscallArg(tc, 0); + // unsigned nbytes = process->getSyscallArg(tc, 2); switch (op) { case 45: { // GSI_IEEE_FP_CONTROL - TypedBufferArg fpcr(tc->getSyscallArg(1)); + TypedBufferArg fpcr(process->getSyscallArg(tc, 1)); // I don't think this exactly matches the HW FPCR *fpcr = 0; fpcr.copyOut(tc->getMemPort()); @@ -94,13 +94,13 @@ static SyscallReturn osf_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = tc->getSyscallArg(0); - // unsigned nbytes = tc->getSyscallArg(2); + unsigned op = process->getSyscallArg(tc, 0); + // unsigned nbytes = process->getSyscallArg(tc, 2); switch (op) { case 14: { // SSI_IEEE_FP_CONTROL - TypedBufferArg fpcr(tc->getSyscallArg(1)); + TypedBufferArg fpcr(process->getSyscallArg(tc, 1)); // I don't think this exactly matches the HW FPCR fpcr.copyIn(tc->getMemPort()); DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): " diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc index 004be1ec0..9c6e62815 100644 --- a/src/arch/alpha/process.cc +++ b/src/arch/alpha/process.cc @@ -42,6 +42,8 @@ using namespace AlphaISA; using namespace std; +static const int SyscallSuccessReg = 19; + AlphaLiveProcess::AlphaLiveProcess(LiveProcessParams *params, ObjectFile *objFile) : LiveProcess(params, objFile) @@ -156,12 +158,10 @@ AlphaLiveProcess::argsInit(int intSize, int pageSize) (uint8_t*)&(auxv[x].a_val), intSize); } - assert(NumArgumentRegs >= 2); - ThreadContext *tc = system->getThreadContext(contextIds[0]); - tc->setIntReg(ArgumentReg[0], argc); - tc->setIntReg(ArgumentReg[1], argv_array_base); + setSyscallArg(tc, 0, argc); + setSyscallArg(tc, 1, argv_array_base); tc->setIntReg(StackPointerReg, stack_min); Addr prog_entry = objFile->entryPoint(); @@ -195,3 +195,35 @@ AlphaLiveProcess::startup() tc->setMiscRegNoEffect(IPR_DTB_ASN, M5_pid << 57); } +AlphaISA::IntReg +AlphaLiveProcess::getSyscallArg(ThreadContext *tc, int i) +{ + assert(i < 6); + return tc->readIntReg(FirstArgumentReg + i); +} + +void +AlphaLiveProcess::setSyscallArg(ThreadContext *tc, + int i, AlphaISA::IntReg val) +{ + assert(i < 6); + tc->setIntReg(FirstArgumentReg + i, val); +} + +void +AlphaLiveProcess::setSyscallReturn(ThreadContext *tc, + SyscallReturn return_value) +{ + // check for error condition. Alpha syscall convention is to + // indicate success/failure in reg a3 (r19) and put the + // return value itself in the standard return value reg (v0). + if (return_value.successful()) { + // no error + tc->setIntReg(SyscallSuccessReg, 0); + tc->setIntReg(ReturnValueReg, return_value.value()); + } else { + // got an error, return details + tc->setIntReg(SyscallSuccessReg, (IntReg)-1); + tc->setIntReg(ReturnValueReg, -return_value.value()); + } +} diff --git a/src/arch/alpha/process.hh b/src/arch/alpha/process.hh index 65c4624ae..6d083c5ac 100644 --- a/src/arch/alpha/process.hh +++ b/src/arch/alpha/process.hh @@ -42,6 +42,11 @@ class AlphaLiveProcess : public LiveProcess void startup(); void argsInit(int intSize, int pageSize); + + public: + AlphaISA::IntReg getSyscallArg(ThreadContext *tc, int i); + void setSyscallArg(ThreadContext *tc, int i, AlphaISA::IntReg val); + void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); }; #endif // __ARCH_ALPHA_PROCESS_HH__ diff --git a/src/arch/alpha/syscallreturn.hh b/src/arch/alpha/syscallreturn.hh deleted file mode 100644 index 776f34fbf..000000000 --- a/src/arch/alpha/syscallreturn.hh +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2003-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Steve Reinhardt - * Gabe Black - */ - -#ifndef __ARCH_ALPHA_SYSCALLRETURN_HH__ -#define __ARCH_ALPHA_SYSCALLRETURN_HH__ - -#include "cpu/thread_context.hh" -#include "sim/syscallreturn.hh" - -namespace AlphaISA { - -static inline void -setSyscallReturn(SyscallReturn return_value, ThreadContext *tc) -{ - // check for error condition. Alpha syscall convention is to - // indicate success/failure in reg a3 (r19) and put the - // return value itself in the standard return value reg (v0). - if (return_value.successful()) { - // no error - tc->setIntReg(SyscallSuccessReg, 0); - tc->setIntReg(ReturnValueReg, return_value.value()); - } else { - // got an error, return details - tc->setIntReg(SyscallSuccessReg, (IntReg)-1); - tc->setIntReg(ReturnValueReg, -return_value.value()); - } -} - -} // namespace AlphaISA - -#endif // __ARCH_ALPHA_SYSCALLRETURN_HH__ diff --git a/src/arch/alpha/tru64/process.cc b/src/arch/alpha/tru64/process.cc index b84dfb286..8fa3cdeda 100644 --- a/src/arch/alpha/tru64/process.cc +++ b/src/arch/alpha/tru64/process.cc @@ -45,7 +45,7 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg name(tc->getSyscallArg(0)); + TypedBufferArg name(process->getSyscallArg(tc, 0)); strcpy(name->sysname, "OSF1"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -62,34 +62,35 @@ static SyscallReturn getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = tc->getSyscallArg(0); - unsigned nbytes = tc->getSyscallArg(2); + unsigned op = process->getSyscallArg(tc, 0); + unsigned nbytes = process->getSyscallArg(tc, 2); switch (op) { case AlphaTru64::GSI_MAX_CPU: { - TypedBufferArg max_cpu(tc->getSyscallArg(1)); + TypedBufferArg max_cpu(process->getSyscallArg(tc, 1)); *max_cpu = htog((uint32_t)process->numCpus()); max_cpu.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_CPUS_IN_BOX: { - TypedBufferArg cpus_in_box(tc->getSyscallArg(1)); + TypedBufferArg cpus_in_box(process->getSyscallArg(tc, 1)); *cpus_in_box = htog((uint32_t)process->numCpus()); cpus_in_box.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_PHYSMEM: { - TypedBufferArg physmem(tc->getSyscallArg(1)); + TypedBufferArg physmem(process->getSyscallArg(tc, 1)); *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB physmem.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_CPU_INFO: { - TypedBufferArg infop(tc->getSyscallArg(1)); + TypedBufferArg + infop(process->getSyscallArg(tc, 1)); infop->current_cpu = htog(0); infop->cpus_in_box = htog(process->numCpus()); @@ -106,14 +107,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, } case AlphaTru64::GSI_PROC_TYPE: { - TypedBufferArg proc_type(tc->getSyscallArg(1)); + TypedBufferArg proc_type(process->getSyscallArg(tc, 1)); *proc_type = htog((uint64_t)11); proc_type.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_PLATFORM_NAME: { - BufferArg bufArg(tc->getSyscallArg(1), nbytes); + BufferArg bufArg(process->getSyscallArg(tc, 1), nbytes); strncpy((char *)bufArg.bufferPtr(), "COMPAQ Professional Workstation XP1000", nbytes); @@ -122,7 +123,7 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, } case AlphaTru64::GSI_CLK_TCK: { - TypedBufferArg clk_hz(tc->getSyscallArg(1)); + TypedBufferArg clk_hz(process->getSyscallArg(tc, 1)); *clk_hz = htog((uint64_t)1024); clk_hz.copyOut(tc->getMemPort()); return 1; @@ -141,12 +142,12 @@ static SyscallReturn setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = tc->getSyscallArg(0); + unsigned op = process->getSyscallArg(tc, 0); switch (op) { case AlphaTru64::SSI_IEEE_FP_CONTROL: warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n", - tc->getSyscallArg(1)); + process->getSyscallArg(tc, 1)); break; default: @@ -164,17 +165,17 @@ tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process, { using namespace std; - int id = tc->getSyscallArg(0); // table ID - int index = tc->getSyscallArg(1); // index into table + int id = process->getSyscallArg(tc, 0); // table ID + int index = process->getSyscallArg(tc, 1); // index into table // arg 2 is buffer pointer; type depends on table ID - int nel = tc->getSyscallArg(3); // number of elements - int lel = tc->getSyscallArg(4); // expected element size + int nel = process->getSyscallArg(tc, 3); // number of elements + int lel = process->getSyscallArg(tc, 4); // expected element size switch (id) { case AlphaTru64::TBL_SYSINFO: { if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo)) return -EINVAL; - TypedBufferArg elp(tc->getSyscallArg(2)); + TypedBufferArg elp(process->getSyscallArg(tc, 2)); const int clk_hz = one_million; elp->si_user = htog(curTick / (Clock::Frequency / clk_hz)); diff --git a/src/arch/alpha/utility.cc b/src/arch/alpha/utility.cc index 2cf64b799..763da0d4f 100644 --- a/src/arch/alpha/utility.cc +++ b/src/arch/alpha/utility.cc @@ -42,11 +42,12 @@ uint64_t getArgument(ThreadContext *tc, int number, bool fp) { #if FULL_SYSTEM + const int NumArgumentRegs = 6; if (number < NumArgumentRegs) { if (fp) - return tc->readFloatRegBits(ArgumentReg[number]); + return tc->readFloatRegBits(16 + number); else - return tc->readIntReg(ArgumentReg[number]); + return tc->readIntReg(16 + number); } else { Addr sp = tc->readIntReg(StackPointerReg); VirtualPort *vp = tc->getVirtPort(); diff --git a/src/arch/mips/isa_traits.hh b/src/arch/mips/isa_traits.hh index 3450c273e..ed4ed9877 100644 --- a/src/arch/mips/isa_traits.hh +++ b/src/arch/mips/isa_traits.hh @@ -190,13 +190,6 @@ namespace MipsISA // semantically meaningful register indices const int ZeroReg = 0; const int AssemblerReg = 1; - const int ReturnValueReg = 2; - const int ReturnValueReg1 = 2; - const int ReturnValueReg2 = 3; - const int ArgumentReg0 = 4; - const int ArgumentReg1 = 5; - const int ArgumentReg2 = 6; - const int ArgumentReg3 = 7; const int KernelReg0 = 26; const int KernelReg1 = 27; const int GlobalPointerReg = 28; @@ -204,12 +197,7 @@ namespace MipsISA const int FramePointerReg = 30; const int ReturnAddressReg = 31; - const int ArgumentReg[] = {4, 5, 6, 7}; - const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int); - - const int SyscallNumReg = ReturnValueReg1; - const int SyscallPseudoReturnReg = ReturnValueReg2; - const int SyscallSuccessReg = ArgumentReg3; + const int SyscallPseudoReturnReg = 3; const int LogVMPageSize = 13; // 8K bytes const int VMPageSize = (1 << LogVMPageSize); diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc index 9d9d33325..dc3b84ced 100644 --- a/src/arch/mips/linux/process.cc +++ b/src/arch/mips/linux/process.cc @@ -51,7 +51,7 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg name(tc->getSyscallArg(0)); + TypedBufferArg name(process->getSyscallArg(tc, 0)); strcpy(name->sysname, "Linux"); strcpy(name->nodename,"m5.eecs.umich.edu"); @@ -70,13 +70,13 @@ static SyscallReturn sys_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = tc->getSyscallArg(0); - // unsigned nbytes = tc->getSyscallArg(2); + unsigned op = process->getSyscallArg(tc, 0); + // unsigned nbytes = process->getSyscallArg(tc, 2); switch (op) { case 45: { // GSI_IEEE_FP_CONTROL - TypedBufferArg fpcr(tc->getSyscallArg(1)); + TypedBufferArg fpcr(process->getSyscallArg(tc, 1)); // I don't think this exactly matches the HW FPCR *fpcr = 0; fpcr.copyOut(tc->getMemPort()); @@ -97,13 +97,13 @@ static SyscallReturn sys_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = tc->getSyscallArg(0); - // unsigned nbytes = tc->getSyscallArg(2); + unsigned op = process->getSyscallArg(tc, 0); + // unsigned nbytes = process->getSyscallArg(tc, 2); switch (op) { case 14: { // SSI_IEEE_FP_CONTROL - TypedBufferArg fpcr(tc->getSyscallArg(1)); + TypedBufferArg fpcr(process->getSyscallArg(tc, 1)); // I don't think this exactly matches the HW FPCR fpcr.copyIn(tc->getMemPort()); DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): " diff --git a/src/arch/mips/process.cc b/src/arch/mips/process.cc index b7bd22d78..784ddfe33 100644 --- a/src/arch/mips/process.cc +++ b/src/arch/mips/process.cc @@ -40,6 +40,10 @@ using namespace std; using namespace MipsISA; +static const int SyscallSuccessReg = 7; +static const int FirstArgumentReg = 4; +static const int ReturnValueReg = 2; + MipsLiveProcess::MipsLiveProcess(LiveProcessParams * params, ObjectFile *objFile) : LiveProcess(params, objFile) @@ -64,3 +68,33 @@ MipsLiveProcess::startup() { argsInit(MachineBytes, VMPageSize); } + +MipsISA::IntReg +MipsLiveProcess::getSyscallArg(ThreadContext *tc, int i) +{ + assert(i < 6); + return tc->readIntReg(FirstArgumentReg + i); +} + +void +MipsLiveProcess::setSyscallArg(ThreadContext *tc, + int i, MipsISA::IntReg val) +{ + assert(i < 6); + tc->setIntReg(FirstArgumentReg + i, val); +} + +void +MipsLiveProcess::setSyscallReturn(ThreadContext *tc, + SyscallReturn return_value) +{ + if (return_value.successful()) { + // no error + tc->setIntReg(SyscallSuccessReg, 0); + tc->setIntReg(ReturnValueReg, return_value.value()); + } else { + // got an error, return details + tc->setIntReg(SyscallSuccessReg, (IntReg) -1); + tc->setIntReg(ReturnValueReg, -return_value.value()); + } +} diff --git a/src/arch/mips/process.hh b/src/arch/mips/process.hh index 18bf289b8..87c62330f 100644 --- a/src/arch/mips/process.hh +++ b/src/arch/mips/process.hh @@ -47,6 +47,10 @@ class MipsLiveProcess : public LiveProcess virtual void startup(); + public: + MipsISA::IntReg getSyscallArg(ThreadContext *tc, int i); + void setSyscallArg(ThreadContext *tc, int i, MipsISA::IntReg val); + void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); }; diff --git a/src/arch/mips/syscallreturn.hh b/src/arch/mips/syscallreturn.hh deleted file mode 100644 index 24a40ddcc..000000000 --- a/src/arch/mips/syscallreturn.hh +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2007 MIPS Technologies, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Gabe Black - * Korey Sewell - */ - -#ifndef __ARCH_MIPS_SYSCALLRETURN_HH__ -#define __ARCH_MIPS_SYSCALLRETURN_HH__ - -#include "sim/syscallreturn.hh" -#include "cpu/thread_context.hh" - -namespace MipsISA -{ - static inline void setSyscallReturn(SyscallReturn return_value, - ThreadContext *tc) - { - if (return_value.successful()) { - // no error - tc->setIntReg(SyscallSuccessReg, 0); - tc->setIntReg(ReturnValueReg1, return_value.value()); - } else { - // got an error, return details - tc->setIntReg(SyscallSuccessReg, (IntReg) -1); - tc->setIntReg(ReturnValueReg1, -return_value.value()); - } - } -} - -#endif diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh index 30455792f..501f2f990 100644 --- a/src/arch/sparc/isa_traits.hh +++ b/src/arch/sparc/isa_traits.hh @@ -68,16 +68,12 @@ namespace SparcISA // semantically meaningful register indices const int ZeroReg = 0; // architecturally meaningful // the rest of these depend on the ABI - const int StackPointerReg = 14; const int ReturnAddressReg = 31; // post call, precall is 15 - const int ReturnValueReg = 8; // Post return, 24 is pre-return. + const int StackPointerReg = 14; const int FramePointerReg = 30; - const int ArgumentReg[] = {8, 9, 10, 11, 12, 13}; - const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int); - // Some OS syscall use a second register (o1) to return a second value - const int SyscallPseudoReturnReg = ArgumentReg[1]; + const int SyscallPseudoReturnReg = 9; //8K. This value is implmentation specific; and should probably //be somewhere else. diff --git a/src/arch/sparc/linux/process.hh b/src/arch/sparc/linux/process.hh index 06eee9235..a76b4b3b2 100644 --- a/src/arch/sparc/linux/process.hh +++ b/src/arch/sparc/linux/process.hh @@ -32,7 +32,6 @@ #define __SPARC_LINUX_PROCESS_HH__ #include "arch/sparc/linux/linux.hh" -#include "arch/sparc/syscallreturn.hh" #include "arch/sparc/process.hh" #include "sim/process.hh" diff --git a/src/arch/sparc/linux/syscalls.cc b/src/arch/sparc/linux/syscalls.cc index 3e8c603cd..8496fca13 100644 --- a/src/arch/sparc/linux/syscalls.cc +++ b/src/arch/sparc/linux/syscalls.cc @@ -29,7 +29,6 @@ */ #include "arch/sparc/linux/process.hh" -#include "arch/sparc/syscallreturn.hh" #include "sim/syscall_emul.hh" class LiveProcess; @@ -42,7 +41,7 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg name(tc->getSyscallArg(0)); + TypedBufferArg name(process->getSyscallArg(tc, 0)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -60,9 +59,9 @@ SyscallReturn getresuidFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { const IntReg id = htog(100); - Addr ruid = tc->getSyscallArg(0); - Addr euid = tc->getSyscallArg(1); - Addr suid = tc->getSyscallArg(2); + Addr ruid = p->getSyscallArg(tc, 0); + Addr euid = p->getSyscallArg(tc, 1); + Addr suid = p->getSyscallArg(tc, 2); //Handle the EFAULT case //Set the ruid if(ruid) diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 515389687..b2b539816 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -46,6 +46,9 @@ using namespace std; using namespace SparcISA; +static const int FirstArgumentReg = 8; +static const int ReturnValueReg = 8; + SparcLiveProcess::SparcLiveProcess(LiveProcessParams * params, ObjectFile *objFile, Addr _StackBias) @@ -509,3 +512,63 @@ void Sparc64LiveProcess::flushWindows(ThreadContext *tc) tc->setIntReg(NumIntArchRegs + 4, Canrestore); tc->setMiscReg(MISCREG_CWP, origCWP); } + +IntReg +Sparc32LiveProcess::getSyscallArg(ThreadContext *tc, int i) +{ + assert(i < 6); + return bits(tc->readIntReg(FirstArgumentReg + i), 31, 0); +} + +void +Sparc32LiveProcess::setSyscallArg(ThreadContext *tc, int i, IntReg val) +{ + assert(i < 6); + tc->setIntReg(FirstArgumentReg + i, bits(val, 31, 0)); +} + +IntReg +Sparc64LiveProcess::getSyscallArg(ThreadContext *tc, int i) +{ + assert(i < 6); + return tc->readIntReg(FirstArgumentReg + i); +} + +void +Sparc64LiveProcess::setSyscallArg(ThreadContext *tc, int i, IntReg val) +{ + assert(i < 6); + tc->setIntReg(FirstArgumentReg + i, val); +} + +void +SparcLiveProcess::setSyscallReturn(ThreadContext *tc, + SyscallReturn return_value) +{ + // check for error condition. SPARC syscall convention is to + // indicate success/failure in reg the carry bit of the ccr + // and put the return value itself in the standard return value reg (). + if (return_value.successful()) { + // no error, clear XCC.C + tc->setIntReg(NumIntArchRegs + 2, + tc->readIntReg(NumIntArchRegs + 2) & 0xEE); + //tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) & 0xEE); + IntReg val = return_value.value(); + if (bits(tc->readMiscRegNoEffect( + SparcISA::MISCREG_PSTATE), 3, 3)) { + val = bits(val, 31, 0); + } + tc->setIntReg(ReturnValueReg, val); + } else { + // got an error, set XCC.C + tc->setIntReg(NumIntArchRegs + 2, + tc->readIntReg(NumIntArchRegs + 2) | 0x11); + //tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) | 0x11); + IntReg val = -return_value.value(); + if (bits(tc->readMiscRegNoEffect( + SparcISA::MISCREG_PSTATE), 3, 3)) { + val = bits(val, 31, 0); + } + tc->setIntReg(ReturnValueReg, val); + } +} diff --git a/src/arch/sparc/process.hh b/src/arch/sparc/process.hh index 95abb93d3..fdb9734ba 100644 --- a/src/arch/sparc/process.hh +++ b/src/arch/sparc/process.hh @@ -69,6 +69,7 @@ class SparcLiveProcess : public LiveProcess { return spillStart; } virtual void flushWindows(ThreadContext *tc) = 0; + void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); }; class Sparc32LiveProcess : public SparcLiveProcess @@ -93,6 +94,9 @@ class Sparc32LiveProcess : public SparcLiveProcess void argsInit(int intSize, int pageSize); void flushWindows(ThreadContext *tc); + + SparcISA::IntReg getSyscallArg(ThreadContext *tc, int i); + void setSyscallArg(ThreadContext *tc, int i, SparcISA::IntReg val); }; class Sparc64LiveProcess : public SparcLiveProcess @@ -118,6 +122,9 @@ class Sparc64LiveProcess : public SparcLiveProcess void argsInit(int intSize, int pageSize); void flushWindows(ThreadContext *tc); + + SparcISA::IntReg getSyscallArg(ThreadContext *tc, int i); + void setSyscallArg(ThreadContext *tc, int i, SparcISA::IntReg val); }; #endif // __SPARC_PROCESS_HH__ diff --git a/src/arch/sparc/solaris/process.cc b/src/arch/sparc/solaris/process.cc index e4f6b23c8..1a4940b59 100644 --- a/src/arch/sparc/solaris/process.cc +++ b/src/arch/sparc/solaris/process.cc @@ -48,7 +48,7 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg name(tc->getSyscallArg(0)); + TypedBufferArg name(process->getSyscallArg(tc, 0)); strcpy(name->sysname, "SunOS"); strcpy(name->nodename, "m5.eecs.umich.edu"); diff --git a/src/arch/sparc/syscallreturn.hh b/src/arch/sparc/syscallreturn.hh deleted file mode 100644 index d4e6c7c50..000000000 --- a/src/arch/sparc/syscallreturn.hh +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2003-2005 The Regents of The University of Michigan - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer; - * redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution; - * neither the name of the copyright holders nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Gabe Black - */ - -#ifndef __ARCH_SPARC_SYSCALLRETURN_HH__ -#define __ARCH_SPARC_SYSCALLRETURN_HH__ - -#include - -#include "sim/syscallreturn.hh" -#include "arch/sparc/regfile.hh" -#include "cpu/thread_context.hh" - -namespace SparcISA -{ - static inline void setSyscallReturn(SyscallReturn return_value, - ThreadContext * tc) - { - // check for error condition. SPARC syscall convention is to - // indicate success/failure in reg the carry bit of the ccr - // and put the return value itself in the standard return value reg (). - if (return_value.successful()) { - // no error, clear XCC.C - tc->setIntReg(NumIntArchRegs + 2, - tc->readIntReg(NumIntArchRegs + 2) & 0xEE); - //tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) & 0xEE); - IntReg val = return_value.value(); - if (bits(tc->readMiscRegNoEffect( - SparcISA::MISCREG_PSTATE), 3, 3)) { - val = bits(val, 31, 0); - } - tc->setIntReg(ReturnValueReg, val); - } else { - // got an error, set XCC.C - tc->setIntReg(NumIntArchRegs + 2, - tc->readIntReg(NumIntArchRegs + 2) | 0x11); - //tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) | 0x11); - IntReg val = -return_value.value(); - if (bits(tc->readMiscRegNoEffect( - SparcISA::MISCREG_PSTATE), 3, 3)) { - val = bits(val, 31, 0); - } - tc->setIntReg(ReturnValueReg, val); - } - } -}; - -#endif diff --git a/src/arch/sparc/utility.cc b/src/arch/sparc/utility.cc index 8f5c3e036..d4cc286e6 100644 --- a/src/arch/sparc/utility.cc +++ b/src/arch/sparc/utility.cc @@ -46,8 +46,9 @@ namespace SparcISA { //first 6 arguments which the caller may use but doesn't have to. uint64_t getArgument(ThreadContext *tc, int number, bool fp) { #if FULL_SYSTEM + const int NumArgumentRegs = 6; if (number < NumArgumentRegs) { - return tc->readIntReg(ArgumentReg[number]); + return tc->readIntReg(8 + number); } else { Addr sp = tc->readIntReg(StackPointerReg); VirtualPort *vp = tc->getVirtPort(); diff --git a/src/arch/x86/isa_traits.hh b/src/arch/x86/isa_traits.hh index abb7694ed..d25e0eb70 100644 --- a/src/arch/x86/isa_traits.hh +++ b/src/arch/x86/isa_traits.hh @@ -106,19 +106,7 @@ namespace X86ISA const int StackPointerReg = INTREG_RSP; //X86 doesn't seem to have a link register const int ReturnAddressReg = 0; - const int ReturnValueReg = INTREG_RAX; const int FramePointerReg = INTREG_RBP; - const int ArgumentReg[] = { - INTREG_RDI, - INTREG_RSI, - INTREG_RDX, - //This argument register is r10 for syscalls and rcx for C. - INTREG_R10W, - //INTREG_RCX, - INTREG_R8W, - INTREG_R9W - }; - const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int); // Some OS syscalls use a second register (rdx) to return a second // value diff --git a/src/arch/x86/linux/process.hh b/src/arch/x86/linux/process.hh index 2f37692e3..ca3606ef0 100644 --- a/src/arch/x86/linux/process.hh +++ b/src/arch/x86/linux/process.hh @@ -60,7 +60,6 @@ #include "sim/process.hh" #include "arch/x86/linux/linux.hh" -#include "arch/x86/syscallreturn.hh" #include "arch/x86/process.hh" namespace X86ISA { diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 324749366..e4e0fa234 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -68,7 +68,7 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg name(tc->getSyscallArg(0)); + TypedBufferArg name(process->getSyscallArg(tc, 0)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -94,8 +94,8 @@ archPrctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process, }; //First argument is the code, second is the address - int code = tc->getSyscallArg(0); - uint64_t addr = tc->getSyscallArg(1); + int code = process->getSyscallArg(tc, 0); + uint64_t addr = process->getSyscallArg(tc, 1); uint64_t fsBase, gsBase; TranslatingPort *p = tc->getMemPort(); switch(code) diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 800dd44ef..7d7978a35 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -104,6 +104,18 @@ using namespace std; using namespace X86ISA; +static const int ReturnValueReg = INTREG_RAX; +static const int ArgumentReg[] = { + INTREG_RDI, + INTREG_RSI, + INTREG_RDX, + //This argument register is r10 for syscalls and rcx for C. + INTREG_R10W, + //INTREG_RCX, + INTREG_R8W, + INTREG_R9W +}; +static const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int); X86LiveProcess::X86LiveProcess(LiveProcessParams * params, ObjectFile *objFile, SyscallDesc *_syscallDescs, int _numSyscallDescs) : @@ -574,3 +586,35 @@ I386LiveProcess::argsInit(int intSize, int pageSize) { X86LiveProcess::argsInit(pageSize); } + +void +X86LiveProcess::setSyscallReturn(ThreadContext *tc, SyscallReturn return_value) +{ + tc->setIntReg(INTREG_RAX, return_value.value()); +} + +X86ISA::IntReg +X86_64LiveProcess::getSyscallArg(ThreadContext *tc, int i) +{ + assert(i < NumArgumentRegs); + return tc->readIntReg(ArgumentReg[i]); +} + +void +X86_64LiveProcess::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val) +{ + assert(i < NumArgumentRegs); + return tc->setIntReg(ArgumentReg[i], val); +} + +X86ISA::IntReg +I386LiveProcess::getSyscallArg(ThreadContext *tc, int i) +{ + panic("32 bit getSyscallArg not implemented.\n"); +} + +void +I386LiveProcess::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val) +{ + panic("32 bit setSyscallArg not implemented.\n"); +} diff --git a/src/arch/x86/process.hh b/src/arch/x86/process.hh index 8d77bd79d..e337e589e 100644 --- a/src/arch/x86/process.hh +++ b/src/arch/x86/process.hh @@ -81,6 +81,8 @@ namespace X86ISA public: SyscallDesc* getDesc(int callnum); + + void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); }; class X86_64LiveProcess : public X86LiveProcess @@ -92,6 +94,9 @@ namespace X86ISA public: void argsInit(int intSize, int pageSize); void startup(); + + X86ISA::IntReg getSyscallArg(ThreadContext *tc, int i); + void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val); }; class I386LiveProcess : public X86LiveProcess @@ -103,6 +108,9 @@ namespace X86ISA public: void argsInit(int intSize, int pageSize); void startup(); + + X86ISA::IntReg getSyscallArg(ThreadContext *tc, int i); + void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val); }; } diff --git a/src/arch/x86/syscallreturn.hh b/src/arch/x86/syscallreturn.hh deleted file mode 100644 index 6a7fdba58..000000000 --- a/src/arch/x86/syscallreturn.hh +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2007 The Hewlett-Packard Development Company - * All rights reserved. - * - * Redistribution and use of this software in source and binary forms, - * with or without modification, are permitted provided that the - * following conditions are met: - * - * The software must be used only for Non-Commercial Use which means any - * use which is NOT directed to receiving any direct monetary - * compensation for, or commercial advantage from such use. Illustrative - * examples of non-commercial use are academic research, personal study, - * teaching, education and corporate research & development. - * Illustrative examples of commercial use are distributing products for - * commercial advantage and providing services using the software for - * commercial advantage. - * - * If you wish to use this software or functionality therein that may be - * covered by patents for commercial use, please contact: - * Director of Intellectual Property Licensing - * Office of Strategy and Technology - * Hewlett-Packard Company - * 1501 Page Mill Road - * Palo Alto, California 94304 - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. Redistributions - * in binary form must reproduce the above copyright notice, this list of - * conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. Neither the name of - * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. No right of - * sublicense is granted herewith. Derivatives of the software and - * output created using the software may be prepared, but only for - * Non-Commercial Uses. Derivatives of the software may be shared with - * others provided: (i) the others agree to abide by the list of - * conditions herein which includes the Non-Commercial Use restrictions; - * and (ii) such Derivatives of the software include the above copyright - * notice to acknowledge the contribution from this software where - * applicable, this list of conditions and the disclaimer below. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Authors: Gabe Black - */ - -#ifndef __ARCH_X86_SYSCALLRETURN_HH__ -#define __ARCH_X86_SYSCALLRETURN_HH__ - -#include "base/misc.hh" -#include "cpu/thread_context.hh" -#include "sim/syscallreturn.hh" - -namespace X86ISA -{ - static inline void setSyscallReturn(SyscallReturn return_value, - ThreadContext * tc) - { - tc->setIntReg(INTREG_RAX, return_value.value()); - } -}; - -#endif // __ARCH_X86_SYSCALLRETURN_HH__ -- cgit v1.2.3 From 6ca53f8675ec0cc31de09d0878b4c29d4048a1fa Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:22:30 -0800 Subject: X86: Handle 32 bit system call arguments. --- src/arch/x86/process.cc | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 7d7978a35..232f07934 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -116,6 +116,14 @@ static const int ArgumentReg[] = { INTREG_R9W }; static const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int); +static const int ArgumentReg32[] = { + INTREG_EBX, + INTREG_ECX, + INTREG_EDX, + INTREG_ESI, + INTREG_EDI, +}; +static const int NumArgumentRegs32 = sizeof(ArgumentReg) / sizeof(const int); X86LiveProcess::X86LiveProcess(LiveProcessParams * params, ObjectFile *objFile, SyscallDesc *_syscallDescs, int _numSyscallDescs) : @@ -260,6 +268,7 @@ I386LiveProcess::startup() tc->setMiscRegNoEffect(MISCREG_SEG_EFF_BASE(seg), 0); tc->setMiscRegNoEffect(MISCREG_SEG_ATTR(seg), dataAttr); tc->setMiscRegNoEffect(MISCREG_SEG_SEL(seg), 0xB); + tc->setMiscRegNoEffect(MISCREG_SEG_LIMIT(seg), (uint32_t)(-1)); } SegAttr csAttr = 0; @@ -610,11 +619,13 @@ X86_64LiveProcess::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val) X86ISA::IntReg I386LiveProcess::getSyscallArg(ThreadContext *tc, int i) { - panic("32 bit getSyscallArg not implemented.\n"); + assert(i < NumArgumentRegs32); + return tc->readIntReg(ArgumentReg32[i]); } void I386LiveProcess::setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val) { - panic("32 bit setSyscallArg not implemented.\n"); + assert(i < NumArgumentRegs); + return tc->setIntReg(ArgumentReg[i], val); } -- cgit v1.2.3 From 14fc06640e82b0a90b737faa18d7232f8fe4c82e Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:22:50 -0800 Subject: X86: Install some 32 bit system calls. --- src/arch/x86/linux/linux.cc | 39 +++++++++++++++++++++++++++++++++++++++ src/arch/x86/linux/linux.hh | 25 +++++++++++++++++++++++++ src/arch/x86/linux/syscalls.cc | 8 ++++---- 3 files changed, 68 insertions(+), 4 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/linux/linux.cc b/src/arch/x86/linux/linux.cc index 5e8d2de16..41855da59 100644 --- a/src/arch/x86/linux/linux.cc +++ b/src/arch/x86/linux/linux.cc @@ -97,3 +97,42 @@ const int X86Linux64::NUM_OPEN_FLAGS = sizeof(X86Linux64::openFlagTable) / sizeof(X86Linux64::openFlagTable[0]); +// open(2) flags translation table +OpenFlagTransTable X86Linux32::openFlagTable[] = { +#ifdef _MSC_VER + { TGT_O_RDONLY, _O_RDONLY }, + { TGT_O_WRONLY, _O_WRONLY }, + { TGT_O_RDWR, _O_RDWR }, + { TGT_O_APPEND, _O_APPEND }, + { TGT_O_CREAT, _O_CREAT }, + { TGT_O_TRUNC, _O_TRUNC }, + { TGT_O_EXCL, _O_EXCL }, +#ifdef _O_NONBLOCK + { TGT_O_NONBLOCK, _O_NONBLOCK }, +#endif +#ifdef _O_NOCTTY + { TGT_O_NOCTTY, _O_NOCTTY }, +#endif +#ifdef _O_SYNC + { TGT_O_SYNC, _O_SYNC }, +#endif +#else /* !_MSC_VER */ + { TGT_O_RDONLY, O_RDONLY }, + { TGT_O_WRONLY, O_WRONLY }, + { TGT_O_RDWR, O_RDWR }, + { TGT_O_APPEND, O_APPEND }, + { TGT_O_CREAT, O_CREAT }, + { TGT_O_TRUNC, O_TRUNC }, + { TGT_O_EXCL, O_EXCL }, + { TGT_O_NONBLOCK, O_NONBLOCK }, + { TGT_O_NOCTTY, O_NOCTTY }, +#ifdef O_SYNC + { TGT_O_SYNC, O_SYNC }, +#endif +#endif /* _MSC_VER */ +}; + +const int X86Linux32::NUM_OPEN_FLAGS = + sizeof(X86Linux32::openFlagTable) / + sizeof(X86Linux32::openFlagTable[0]); + diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh index dbc336da1..c45caa19f 100644 --- a/src/arch/x86/linux/linux.hh +++ b/src/arch/x86/linux/linux.hh @@ -113,4 +113,29 @@ class X86Linux64 : public Linux } tgt_iovec; }; +class X86Linux32 : public Linux +{ + public: + + static OpenFlagTransTable openFlagTable[]; + + static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY + static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY + static const int TGT_O_RDWR = 00000002; //!< O_RDWR + static const int TGT_O_NONBLOCK = 00004000; //!< O_NONBLOCK + static const int TGT_O_APPEND = 00002000; //!< O_APPEND + static const int TGT_O_CREAT = 00000100; //!< O_CREAT + static const int TGT_O_TRUNC = 00001000; //!< O_TRUNC + static const int TGT_O_EXCL = 00000200; //!< O_EXCL + static const int TGT_O_NOCTTY = 00000400; //!< O_NOCTTY + static const int TGT_O_SYNC = 00010000; //!< O_SYNC +// static const int TGT_O_DRD = 0x00010000; //!< O_DRD +// static const int TGT_O_DIRECTIO = 0x00020000; //!< O_DIRECTIO +// static const int TGT_O_CACHE = 0x00002000; //!< O_CACHE +// static const int TGT_O_DSYNC = 0x00008000; //!< O_DSYNC +// static const int TGT_O_RSYNC = 0x00040000; //!< O_RSYNC + + static const int NUM_OPEN_FLAGS; +}; + #endif diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index e4e0fa234..6c44785d2 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -404,7 +404,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 2 */ SyscallDesc("fork", unimplementedFunc), /* 3 */ SyscallDesc("read", unimplementedFunc), /* 4 */ SyscallDesc("write", unimplementedFunc), - /* 5 */ SyscallDesc("open", unimplementedFunc), + /* 5 */ SyscallDesc("open", openFunc), /* 6 */ SyscallDesc("close", unimplementedFunc), /* 7 */ SyscallDesc("waitpid", unimplementedFunc), /* 8 */ SyscallDesc("creat", unimplementedFunc), @@ -444,7 +444,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 42 */ SyscallDesc("pipe", unimplementedFunc), /* 43 */ SyscallDesc("times", unimplementedFunc), /* 44 */ SyscallDesc("prof", unimplementedFunc), - /* 45 */ SyscallDesc("brk", unimplementedFunc), + /* 45 */ SyscallDesc("brk", brkFunc), /* 46 */ SyscallDesc("setgid", unimplementedFunc), /* 47 */ SyscallDesc("getgid", unimplementedFunc), /* 48 */ SyscallDesc("signal", unimplementedFunc), @@ -521,7 +521,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 119 */ SyscallDesc("sigreturn", unimplementedFunc), /* 120 */ SyscallDesc("clone", unimplementedFunc), /* 121 */ SyscallDesc("setdomainname", unimplementedFunc), - /* 122 */ SyscallDesc("uname", unimplementedFunc), + /* 122 */ SyscallDesc("uname", unameFunc), /* 123 */ SyscallDesc("modify_ldt", unimplementedFunc), /* 124 */ SyscallDesc("adjtimex", unimplementedFunc), /* 125 */ SyscallDesc("mprotect", unimplementedFunc), @@ -545,7 +545,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 143 */ SyscallDesc("flock", unimplementedFunc), /* 144 */ SyscallDesc("msync", unimplementedFunc), /* 145 */ SyscallDesc("readv", unimplementedFunc), - /* 146 */ SyscallDesc("writev", unimplementedFunc), + /* 146 */ SyscallDesc("writev", writevFunc), /* 147 */ SyscallDesc("getsid", unimplementedFunc), /* 148 */ SyscallDesc("fdatasync", unimplementedFunc), /* 149 */ SyscallDesc("_sysctl", unimplementedFunc), -- cgit v1.2.3 From 281ef8111a15e8501cee03fdf35e0c41437518e2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:23:00 -0800 Subject: X86: Compute shift instruction flags correctly. --- .../general_purpose/rotate_and_shift/shift.py | 54 +++++++++++----------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py b/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py index ed7d761b8..138082eb2 100644 --- a/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py +++ b/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py @@ -56,13 +56,13 @@ microcode = ''' def macroop SAL_R_I { - slli reg, reg, imm, flags=(SF,ZF,PF) + slli reg, reg, imm, flags=(CF,OF,SF,ZF,PF) }; def macroop SAL_M_I { ldst t1, seg, sib, disp - slli t1, t1, imm, flags=(SF,ZF,PF) + slli t1, t1, imm, flags=(CF,OF,SF,ZF,PF) st t1, seg, sib, disp }; @@ -70,19 +70,19 @@ def macroop SAL_P_I { rdip t7 ldst t1, seg, riprel, disp - slli t1, t1, imm, flags=(SF,ZF,PF) + slli t1, t1, imm, flags=(CF,OF,SF,ZF,PF) st t1, seg, riprel, disp }; def macroop SAL_1_R { - slli reg, reg, 1, flags=(SF,ZF,PF) + slli reg, reg, 1, flags=(CF,OF,SF,ZF,PF) }; def macroop SAL_1_M { ldst t1, seg, sib, disp - slli t1, t1, 1, flags=(SF,ZF,PF) + slli t1, t1, 1, flags=(CF,OF,SF,ZF,PF) st t1, seg, sib, disp }; @@ -90,19 +90,19 @@ def macroop SAL_1_P { rdip t7 ldst t1, seg, riprel, disp - slli t1, t1, 1, flags=(SF,ZF,PF) + slli t1, t1, 1, flags=(CF,OF,SF,ZF,PF) st t1, seg, riprel, disp }; def macroop SAL_R_R { - sll reg, reg, regm, flags=(SF,ZF,PF) + sll reg, reg, regm, flags=(CF,OF,SF,ZF,PF) }; def macroop SAL_M_R { ldst t1, seg, sib, disp - sll t1, t1, reg, flags=(SF,ZF,PF) + sll t1, t1, reg, flags=(CF,OF,SF,ZF,PF) st t1, seg, sib, disp }; @@ -110,19 +110,19 @@ def macroop SAL_P_R { rdip t7 ldst t1, seg, riprel, disp - sll t1, t1, reg, flags=(SF,ZF,PF) + sll t1, t1, reg, flags=(CF,OF,SF,ZF,PF) st t1, seg, riprel, disp }; def macroop SHR_R_I { - srli reg, reg, imm, flags=(SF,ZF,PF) + srli reg, reg, imm, flags=(CF,OF,SF,ZF,PF) }; def macroop SHR_M_I { ldst t1, seg, sib, disp - srli t1, t1, imm, flags=(SF,ZF,PF) + srli t1, t1, imm, flags=(CF,OF,SF,ZF,PF) st t1, seg, sib, disp }; @@ -130,19 +130,19 @@ def macroop SHR_P_I { rdip t7 ldst t1, seg, riprel, disp - srli t1, t1, imm, flags=(SF,ZF,PF) + srli t1, t1, imm, flags=(CF,OF,SF,ZF,PF) st t1, seg, riprel, disp }; def macroop SHR_1_R { - srli reg, reg, 1, flags=(SF,ZF,PF) + srli reg, reg, 1, flags=(CF,OF,SF,ZF,PF) }; def macroop SHR_1_M { ldst t1, seg, sib, disp - srli t1, t1, 1, flags=(SF,ZF,PF) + srli t1, t1, 1, flags=(CF,OF,SF,ZF,PF) st t1, seg, sib, disp }; @@ -150,19 +150,19 @@ def macroop SHR_1_P { rdip t7 ldst t1, seg, riprel, disp - srli t1, t1, 1, flags=(SF,ZF,PF) + srli t1, t1, 1, flags=(CF,OF,SF,ZF,PF) st t1, seg, riprel, disp }; def macroop SHR_R_R { - srl reg, reg, regm, flags=(SF,ZF,PF) + srl reg, reg, regm, flags=(CF,OF,SF,ZF,PF) }; def macroop SHR_M_R { ldst t1, seg, sib, disp - srl t1, t1, reg, flags=(SF,ZF,PF) + srl t1, t1, reg, flags=(CF,OF,SF,ZF,PF) st t1, seg, sib, disp }; @@ -170,19 +170,19 @@ def macroop SHR_P_R { rdip t7 ldst t1, seg, riprel, disp - srl t1, t1, reg, flags=(SF,ZF,PF) + srl t1, t1, reg, flags=(CF,OF,SF,ZF,PF) st t1, seg, riprel, disp }; def macroop SAR_R_I { - srai reg, reg, imm, flags=(SF,ZF,PF) + srai reg, reg, imm, flags=(CF,OF,SF,ZF,PF) }; def macroop SAR_M_I { ldst t1, seg, sib, disp - srai t1, t1, imm, flags=(SF,ZF,PF) + srai t1, t1, imm, flags=(CF,OF,SF,ZF,PF) st t1, seg, sib, disp }; @@ -190,19 +190,19 @@ def macroop SAR_P_I { rdip t7 ldst t1, seg, riprel, disp - srai t1, t1, imm, flags=(SF,ZF,PF) + srai t1, t1, imm, flags=(CF,OF,SF,ZF,PF) st t1, seg, riprel, disp }; def macroop SAR_1_R { - srai reg, reg, 1, flags=(SF,ZF,PF) + srai reg, reg, 1, flags=(CF,OF,SF,ZF,PF) }; def macroop SAR_1_M { ldst t1, seg, sib, disp - srai t1, t1, 1, flags=(SF,ZF,PF) + srai t1, t1, 1, flags=(CF,OF,SF,ZF,PF) st t1, seg, sib, disp }; @@ -210,19 +210,19 @@ def macroop SAR_1_P { rdip t7 ldst t1, seg, riprel, disp - srai t1, t1, 1, flags=(SF,ZF,PF) + srai t1, t1, 1, flags=(CF,OF,SF,ZF,PF) st t1, seg, riprel, disp }; def macroop SAR_R_R { - sra reg, reg, regm, flags=(SF,ZF,PF) + sra reg, reg, regm, flags=(CF,OF,SF,ZF,PF) }; def macroop SAR_M_R { ldst t1, seg, sib, disp - sra t1, t1, reg, flags=(SF,ZF,PF) + sra t1, t1, reg, flags=(CF,OF,SF,ZF,PF) st t1, seg, sib, disp }; @@ -230,7 +230,7 @@ def macroop SAR_P_R { rdip t7 ldst t1, seg, riprel, disp - sra t1, t1, reg, flags=(SF,ZF,PF) + sra t1, t1, reg, flags=(CF,OF,SF,ZF,PF) st t1, seg, riprel, disp }; ''' -- cgit v1.2.3 From e23d688d8f7e728e694f15752cd70df84bc4ae67 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:23:17 -0800 Subject: X86: Set up a space for a GDT in SE so we can set up TLS or LDT segments. --- src/arch/x86/process.cc | 18 ++++++++++++++++++ src/arch/x86/process.hh | 9 +++++++++ 2 files changed, 27 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 232f07934..22030cbfa 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -251,6 +251,20 @@ I386LiveProcess::startup() argsInit(sizeof(uint32_t), VMPageSize); + /* + * Set up a GDT for this process. The whole GDT wouldn't really be for + * this process, but the only parts we care about are. + */ + _gdtStart = stack_base; + _gdtSize = VMPageSize; + pTable->allocate(_gdtStart, _gdtSize); + uint64_t zero = 0; + assert(_gdtSize % sizeof(zero) == 0); + for (Addr gdtCurrent = _gdtStart; + gdtCurrent < _gdtStart + _gdtSize; gdtCurrent += sizeof(zero)) { + initVirtMem->write(gdtCurrent, zero); + } + for (int i = 0; i < contextIds.size(); i++) { ThreadContext * tc = system->getThreadContext(contextIds[i]); @@ -281,6 +295,10 @@ I386LiveProcess::startup() tc->setMiscRegNoEffect(MISCREG_CS_ATTR, csAttr); + tc->setMiscRegNoEffect(MISCREG_TSG_BASE, _gdtStart); + tc->setMiscRegNoEffect(MISCREG_TSG_EFF_BASE, _gdtStart); + tc->setMiscRegNoEffect(MISCREG_TSG_LIMIT, _gdtStart + _gdtSize - 1); + //Set up the registers that describe the operating mode. CR0 cr0 = 0; cr0.pg = 1; // Turn on paging. diff --git a/src/arch/x86/process.hh b/src/arch/x86/process.hh index e337e589e..2d72d3fd0 100644 --- a/src/arch/x86/process.hh +++ b/src/arch/x86/process.hh @@ -70,6 +70,9 @@ namespace X86ISA class X86LiveProcess : public LiveProcess { protected: + Addr _gdtStart; + Addr _gdtSize; + SyscallDesc *syscallDescs; const int numSyscallDescs; @@ -80,6 +83,12 @@ namespace X86ISA void argsInit(int pageSize); public: + Addr gdtStart() + { return _gdtStart; } + + Addr gdtSize() + { return _gdtSize; } + SyscallDesc* getDesc(int callnum); void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); -- cgit v1.2.3 From 1786f200587384d595851972b2f4b9bdd70175ac Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:23:27 -0800 Subject: X86: Set an initial value for the LDT selector. --- src/arch/x86/process.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 22030cbfa..54d5d07ab 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -299,6 +299,9 @@ I386LiveProcess::startup() tc->setMiscRegNoEffect(MISCREG_TSG_EFF_BASE, _gdtStart); tc->setMiscRegNoEffect(MISCREG_TSG_LIMIT, _gdtStart + _gdtSize - 1); + // Set the LDT selector to 0 to deactivate it. + tc->setMiscRegNoEffect(MISCREG_TSL, 0); + //Set up the registers that describe the operating mode. CR0 cr0 = 0; cr0.pg = 1; // Turn on paging. -- cgit v1.2.3 From 9491debaa623aa0ed148ca4bc810f099058b67a1 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:23:42 -0800 Subject: X86: Implement the 32 bit set_thread_area system call. --- src/arch/x86/linux/syscalls.cc | 107 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 6c44785d2..eacbf5e7b 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -122,6 +122,111 @@ archPrctlFunc(SyscallDesc *desc, int callnum, LiveProcess *process, } } +BitUnion32(UserDescFlags) + Bitfield<0> seg_32bit; + Bitfield<2, 1> contents; + Bitfield<3> read_exec_only; + Bitfield<4> limit_in_pages; + Bitfield<5> seg_not_present; + Bitfield<6> useable; +EndBitUnion(UserDescFlags) + +struct UserDesc32 { + uint32_t entry_number; + uint32_t base_addr; + uint32_t limit; + uint32_t flags; +}; + +struct UserDesc64 { + uint32_t entry_number; + uint32_t __padding1; + uint64_t base_addr; + uint32_t limit; + uint32_t flags; +}; + +static SyscallReturn +setThreadArea32Func(SyscallDesc *desc, int callnum, + LiveProcess *process, ThreadContext *tc) +{ + const int minTLSEntry = 6; + const int numTLSEntries = 3; + const int maxTLSEntry = minTLSEntry + numTLSEntries - 1; + + X86LiveProcess *x86lp = dynamic_cast(process); + assert(x86lp); + + assert((maxTLSEntry + 1) * sizeof(uint64_t) <= x86lp->gdtSize()); + + TypedBufferArg userDesc(process->getSyscallArg(tc, 0)); + TypedBufferArg + gdt(x86lp->gdtStart() + minTLSEntry * sizeof(uint64_t), + numTLSEntries * sizeof(uint64_t)); + + if (!userDesc.copyIn(tc->getMemPort())) + return -EFAULT; + + if (!gdt.copyIn(tc->getMemPort())) + panic("Failed to copy in GDT for %s.\n", desc->name); + + if (userDesc->entry_number == (uint32_t)(-1)) { + // Find a free TLS entry. + for (int i = 0; i < numTLSEntries; i++) { + if (gdt[i] == 0) { + userDesc->entry_number = i + minTLSEntry; + break; + } + } + // We failed to find one. + if (userDesc->entry_number == (uint32_t)(-1)) + return -ESRCH; + } + + int index = userDesc->entry_number; + + if (index < minTLSEntry || index > maxTLSEntry) + return -EINVAL; + + index -= minTLSEntry; + + // Build the entry we're going to add. + SegDescriptor segDesc = 0; + UserDescFlags flags = userDesc->flags; + + segDesc.limitLow = bits(userDesc->limit, 15, 0); + segDesc.baseLow = bits(userDesc->base_addr, 23, 0); + segDesc.type.a = 1; + if (!flags.read_exec_only) + segDesc.type.w = 1; + if (bits((uint8_t)flags.contents, 0)) + segDesc.type.e = 1; + if (bits((uint8_t)flags.contents, 1)) + segDesc.type.codeOrData = 1; + segDesc.s = 1; + segDesc.dpl = 3; + if (!flags.seg_not_present) + segDesc.p = 1; + segDesc.limitHigh = bits(userDesc->limit, 19, 16); + if (flags.useable) + segDesc.avl = 1; + segDesc.l = 0; + if (flags.seg_32bit) + segDesc.d = 1; + if (flags.limit_in_pages) + segDesc.g = 1; + segDesc.baseHigh = bits(userDesc->base_addr, 31, 24); + + gdt[index] = (uint64_t)segDesc; + + if (!userDesc.copyOut(tc->getMemPort())) + return -EFAULT; + if (!gdt.copyOut(tc->getMemPort())) + panic("Failed to copy out GDT for %s.\n", desc->name); + + return 0; +} + SyscallDesc X86_64LinuxProcess::syscallDescs[] = { /* 0 */ SyscallDesc("read", readFunc), /* 1 */ SyscallDesc("write", writeFunc), @@ -642,7 +747,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 240 */ SyscallDesc("futex", unimplementedFunc), /* 241 */ SyscallDesc("sched_setaffinity", unimplementedFunc), /* 242 */ SyscallDesc("sched_getaffinity", unimplementedFunc), - /* 243 */ SyscallDesc("set_thread_area", unimplementedFunc), + /* 243 */ SyscallDesc("set_thread_area", setThreadArea32Func), /* 244 */ SyscallDesc("get_thread_area", unimplementedFunc), /* 245 */ SyscallDesc("io_setup", unimplementedFunc), /* 246 */ SyscallDesc("io_destroy", unimplementedFunc), -- cgit v1.2.3 From 9dfa3f7f735ead0ada9eb79227f217d0d76e0f49 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:23:50 -0800 Subject: X86: Fix segment limit checks. --- src/arch/x86/insts/microldstop.hh | 3 ++- src/arch/x86/isa/microops/ldstop.isa | 4 +++- src/arch/x86/tlb.cc | 36 ++++++++++++++++-------------------- 3 files changed, 21 insertions(+), 22 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/insts/microldstop.hh b/src/arch/x86/insts/microldstop.hh index f0051e2cf..1774454c3 100644 --- a/src/arch/x86/insts/microldstop.hh +++ b/src/arch/x86/insts/microldstop.hh @@ -67,7 +67,8 @@ namespace X86ISA static const Request::FlagsType SegmentFlagMask = mask(4); static const int FlagShift = 4; enum FlagBit { - CPL0FlagBit = 1 + CPL0FlagBit = 1, + AddrSizeFlagBit = 2 }; /** diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index 3bc238174..834b3947f 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -375,6 +375,8 @@ let {{ self.memFlags += " | (CPL0FlagBit << FlagShift)" if prefetch: self.memFlags += " | Request::PF_EXCLUSIVE" + self.memFlags += " | (machInst.legacy.addr ? " + \ + "(AddrSizeFlagBit << FlagShift) : 0)" def getAllocator(self, *microFlags): allocator = '''new %(class_name)s(machInst, macrocodeBlock @@ -439,7 +441,7 @@ let {{ defineMicroLoadOp('Ldfp', 'FpData.uqw = Mem;') def defineMicroStoreOp(mnemonic, code, \ - postCode="", completeCode="", mem_flags=0): + postCode="", completeCode="", mem_flags="0"): global header_output global decoder_output global exec_output diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 603d4e45f..47a2eb37e 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -575,38 +575,34 @@ TLB::translate(RequestPtr req, ThreadContext *tc, if (!tc->readMiscRegNoEffect(MISCREG_SEG_SEL(seg))) return new GeneralProtection(0); bool expandDown = false; + SegAttr attr = tc->readMiscRegNoEffect(MISCREG_SEG_ATTR(seg)); if (seg >= SEGMENT_REG_ES && seg <= SEGMENT_REG_HS) { - SegAttr attr = tc->readMiscRegNoEffect(MISCREG_SEG_ATTR(seg)); if (!attr.writable && write) return new GeneralProtection(0); if (!attr.readable && !write && !execute) return new GeneralProtection(0); expandDown = attr.expandDown; + } Addr base = tc->readMiscRegNoEffect(MISCREG_SEG_BASE(seg)); Addr limit = tc->readMiscRegNoEffect(MISCREG_SEG_LIMIT(seg)); + // This assumes we're not in 64 bit mode. If we were, the default + // address size is 64 bits, overridable to 32. + int size = 32; + bool sizeOverride = (flags & (AddrSizeFlagBit << FlagShift)); + if (csAttr.defaultSize && sizeOverride || + !csAttr.defaultSize && !sizeOverride) + size = 16; + Addr offset = bits(vaddr - base, size-1, 0); + Addr endOffset = offset + req->getSize() - 1; if (expandDown) { DPRINTF(TLB, "Checking an expand down segment.\n"); - // We don't have to worry about the access going around the - // end of memory because accesses will be broken up into - // pieces at boundaries aligned on sizes smaller than an - // entire address space. We do have to worry about the limit - // being less than the base. - if (limit < base) { - if (limit < vaddr + req->getSize() && vaddr < base) - return new GeneralProtection(0); - } else { - if (limit < vaddr + req->getSize()) - return new GeneralProtection(0); - } + warn_once("Expand down segments are untested.\n"); + if (offset <= limit || endOffset <= limit) + return new GeneralProtection(0); } else { - if (limit < base) { - if (vaddr <= limit || vaddr + req->getSize() >= base) - return new GeneralProtection(0); - } else { - if (vaddr <= limit && vaddr + req->getSize() >= base) - return new GeneralProtection(0); - } + if (offset > limit || endOffset > limit) + return new GeneralProtection(0); } } // If paging is enabled, do the translation. -- cgit v1.2.3 From 3dfa564e70e4804ef118ba94c81233fb85f56ba2 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:23:58 -0800 Subject: X86: Respect segment override prefixes even when there's no ModRM byte. --- src/arch/x86/emulenv.cc | 8 ++++++++ src/arch/x86/emulenv.hh | 1 + src/arch/x86/isa/macroop.isa | 11 +++++++---- 3 files changed, 16 insertions(+), 4 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/emulenv.cc b/src/arch/x86/emulenv.cc index 30ed80942..0d7b32130 100644 --- a/src/arch/x86/emulenv.cc +++ b/src/arch/x86/emulenv.cc @@ -105,3 +105,11 @@ void EmulEnv::doModRM(const ExtMachInst & machInst) } } +void EmulEnv::setSeg(const ExtMachInst & machInst) +{ + seg = SEGMENT_REG_DS; + //Handle any segment override that might have been in the instruction + int segFromInst = machInst.legacy.seg; + if (segFromInst) + seg = (SegmentRegIndex)(segFromInst - 1); +} diff --git a/src/arch/x86/emulenv.hh b/src/arch/x86/emulenv.hh index 1044dbdf9..cdb1bf863 100644 --- a/src/arch/x86/emulenv.hh +++ b/src/arch/x86/emulenv.hh @@ -86,6 +86,7 @@ namespace X86ISA {;} void doModRM(const ExtMachInst & machInst); + void setSeg(const ExtMachInst & machInst); }; }; diff --git a/src/arch/x86/isa/macroop.isa b/src/arch/x86/isa/macroop.isa index 8eaf5f786..3a836ff68 100644 --- a/src/arch/x86/isa/macroop.isa +++ b/src/arch/x86/isa/macroop.isa @@ -135,7 +135,7 @@ def template MacroConstructor {{ %(adjust_env)s; %(adjust_imm)s; %(adjust_disp)s; - %(do_modrm)s; + %(init_env)s; %(constructor)s; const char *macrocodeBlock = "%(class_name)s"; //alloc_microops is the code that sets up the microops @@ -166,7 +166,7 @@ let {{ } self.declared = False self.adjust_env = "" - self.doModRM = "" + self.init_env = "" self.adjust_imm = ''' uint64_t adjustedImm = IMMEDIATE; //This is to pacify gcc in case the immediate isn't used. @@ -228,7 +228,7 @@ let {{ "adjust_disp" : self.adjust_disp, "disassembly" : env.disassembly, "regSize" : regSize, - "do_modrm" : self.doModRM}) + "init_env" : self.initEnv}) return MacroConstructor.subst(iop) + \ MacroDisassembly.subst(iop); }}; @@ -304,6 +304,7 @@ let {{ let {{ doModRMString = "env.doModRM(machInst);\n" + noModRMString = "env.setSeg(machInst);\n" def genMacroop(Name, env): blocks = OutputBlocks() if not macroopDict.has_key(Name): @@ -311,7 +312,9 @@ let {{ macroop = macroopDict[Name] if not macroop.declared: if env.doModRM: - macroop.doModRM = doModRMString + macroop.initEnv = doModRMString + else: + macroop.initEnv = noModRMString blocks.header_output = macroop.getDeclaration() blocks.decoder_output = macroop.getDefinition(env) macroop.declared = True -- cgit v1.2.3 From 79bc1b37400ffc4aacfbf19b64aed4c7d568c941 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:24:10 -0800 Subject: X86: Fix a decoder bug and add in some missing instructions. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index 9c376e2c4..64920bcbd 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -829,20 +829,25 @@ 0x4: shrd_Ev_Gv_Ib(); 0x5: shrd_Ev_Gv_rCl(); //0x6: group16(); - 0x6: decode MODRM_MOD { - 0x3: decode MODRM_REG { - 0x5: BasicOperate::LFENCE( + 0x6: decode MODRM_REG { + 0x0: fxsave(); + 0x1: fxrstor(); + 0x2: ldmxcsr(); + 0x3: stmxcsr(); + 0x4: Inst::UD2(); + 0x5: decode MODRM_MOD { + 0x3: BasicOperate::LFENCE( {{/*Nothing*/}}, IsReadBarrier); - 0x6: BasicOperate::MFENCE( + default: Inst::UD2(); + } + 0x6: decode MODRM_MOD { + 0x3: BasicOperate::MFENCE( {{/*Nothing*/}}, IsMemBarrier); - 0x7: BasicOperate::SFENCE( - {{/*Nothing*/}}, IsWriteBarrier); default: Inst::UD2(); } - default: decode MODRM_REG { - 0x0: fxsave(); - 0x1: fxrstor(); - 0x7: clflush(); + 0x7: decode MODRM_MOD { + 0x3: BasicOperate::SFENCE( + {{/*Nothing*/}}, IsWriteBarrier); default: Inst::UD2(); } } -- cgit v1.2.3 From 1d18eb9043d5d2e69d3885be8dd59695ad80a92d Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:25:02 -0800 Subject: X86: Make instructions that use intseg preserve all 8 bytes of their addresses. --- src/arch/x86/isa/insts/general_purpose/input_output/general_io.py | 8 ++++---- src/arch/x86/isa/insts/system/msrs.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/input_output/general_io.py b/src/arch/x86/isa/insts/general_purpose/input_output/general_io.py index 924bfcb6e..4e3c9b316 100644 --- a/src/arch/x86/isa/insts/general_purpose/input_output/general_io.py +++ b/src/arch/x86/isa/insts/general_purpose/input_output/general_io.py @@ -85,22 +85,22 @@ microcode = ''' def macroop IN_R_I { .adjust_imm trimImm(8) limm t1, imm, dataSize=asz - ld reg, intseg, [1, t1, t0], "IntAddrPrefixIO << 3", addressSize=4 + ld reg, intseg, [1, t1, t0], "IntAddrPrefixIO << 3", addressSize=8 }; def macroop IN_R_R { zexti t2, regm, 15, dataSize=8 - ld reg, intseg, [1, t2, t0], "IntAddrPrefixIO << 3", addressSize=4 + ld reg, intseg, [1, t2, t0], "IntAddrPrefixIO << 3", addressSize=8 }; def macroop OUT_I_R { .adjust_imm trimImm(8) limm t1, imm, dataSize=8 - st reg, intseg, [1, t1, t0], "IntAddrPrefixIO << 3", addressSize=4 + st reg, intseg, [1, t1, t0], "IntAddrPrefixIO << 3", addressSize=8 }; def macroop OUT_R_R { zexti t2, reg, 15, dataSize=8 - st regm, intseg, [1, t2, t0], "IntAddrPrefixIO << 3", addressSize=4 + st regm, intseg, [1, t2, t0], "IntAddrPrefixIO << 3", addressSize=8 }; ''' diff --git a/src/arch/x86/isa/insts/system/msrs.py b/src/arch/x86/isa/insts/system/msrs.py index f3c867398..7f283c8c1 100644 --- a/src/arch/x86/isa/insts/system/msrs.py +++ b/src/arch/x86/isa/insts/system/msrs.py @@ -85,7 +85,7 @@ microcode = ''' def macroop RDMSR { ld t2, intseg, [8, rcx, t0], "IntAddrPrefixMSR << 3", \ - dataSize=8, addressSize=4 + dataSize=8, addressSize=8 mov rax, rax, t2, dataSize=4 srli t2, t2, 32, dataSize=8 mov rdx, rdx, t2, dataSize=4 @@ -97,7 +97,7 @@ def macroop WRMSR slli t3, rdx, 32, dataSize=8 or t2, t2, t3, dataSize=8 st t2, intseg, [8, rcx, t0], "IntAddrPrefixMSR << 3", \ - dataSize=8, addressSize=4 + dataSize=8, addressSize=8 }; def macroop RDTSC -- cgit v1.2.3 From 8a1eb7e8bec41d41daf3e35b30a11e04f6285f66 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:25:16 -0800 Subject: X86: Take address size into account when computing an effective address. --- src/arch/x86/isa/microops/ldstop.isa | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index 834b3947f..af94cf31e 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -402,7 +402,9 @@ let {{ decoder_output = "" exec_output = "" - calculateEA = "EA = SegBase + scale * Index + Base + disp;" + calculateEA = ''' + EA = bits(SegBase + scale * Index + Base + disp, addressSize * 8 - 1, 0); + ''' def defineMicroLoadOp(mnemonic, code, mem_flags="0"): global header_output -- cgit v1.2.3 From 04dbed79f8c9b3069644f60b7b1087df392edd59 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:25:26 -0800 Subject: X86: Install a 32 bit fstat64 system call. --- src/arch/x86/linux/syscalls.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index eacbf5e7b..1d2d8d691 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -701,7 +701,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 194 */ SyscallDesc("ftruncate64", unimplementedFunc), /* 195 */ SyscallDesc("stat64", unimplementedFunc), /* 196 */ SyscallDesc("lstat64", unimplementedFunc), - /* 197 */ SyscallDesc("fstat64", unimplementedFunc), + /* 197 */ SyscallDesc("fstat64", fstat64Func), /* 198 */ SyscallDesc("lchown32", unimplementedFunc), /* 199 */ SyscallDesc("getuid32", unimplementedFunc), /* 200 */ SyscallDesc("getgid32", unimplementedFunc), -- cgit v1.2.3 From 5c1cc99d486870bb6942980474b535ec0917f85c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:25:33 -0800 Subject: X86: Add a 32 bit mmap2 system call. --- src/arch/x86/linux/linux.hh | 2 ++ src/arch/x86/linux/syscalls.cc | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh index c45caa19f..c6fe28318 100644 --- a/src/arch/x86/linux/linux.hh +++ b/src/arch/x86/linux/linux.hh @@ -136,6 +136,8 @@ class X86Linux32 : public Linux // static const int TGT_O_RSYNC = 0x00040000; //!< O_RSYNC static const int NUM_OPEN_FLAGS; + + static const unsigned TGT_MAP_ANONYMOUS = 0x20; }; #endif diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 1d2d8d691..7969f2e41 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -696,7 +696,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 189 */ SyscallDesc("putpmsg", unimplementedFunc), /* 190 */ SyscallDesc("vfork", unimplementedFunc), /* 191 */ SyscallDesc("ugetrlimit", unimplementedFunc), - /* 192 */ SyscallDesc("mmap2", unimplementedFunc), + /* 192 */ SyscallDesc("mmap2", mmapFunc), /* 193 */ SyscallDesc("truncate64", unimplementedFunc), /* 194 */ SyscallDesc("ftruncate64", unimplementedFunc), /* 195 */ SyscallDesc("stat64", unimplementedFunc), -- cgit v1.2.3 From c3d7d7ed0e3931d549a14ef8b32a1619861f3ef0 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:25:43 -0800 Subject: X86: Implement sysenter as a system call interface. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index 64920bcbd..c3fb5c19d 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -420,7 +420,11 @@ 0x1: Inst::RDTSC(); 0x2: Inst::RDMSR(); 0x3: rdpmc(); +#if FULL_SYSTEM 0x4: sysenter(); +#else + 0x4: SyscallInst::sysenter('xc->syscall(Rax)', IsSyscall); +#endif 0x5: sysexit(); 0x6: Inst::UD2(); 0x7: getsec(); -- cgit v1.2.3 From db3c51d3a02864594c23f25b9e18825327703643 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:25:51 -0800 Subject: X86: Add a vsyscall page for 32 bit processes to use. --- src/arch/x86/process.cc | 60 +++++++++++++++++++++++++++++++++++++++++++------ src/arch/x86/process.hh | 14 +++++++++++- 2 files changed, 66 insertions(+), 8 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc index 54d5d07ab..4a61ed168 100644 --- a/src/arch/x86/process.cc +++ b/src/arch/x86/process.cc @@ -152,12 +152,32 @@ X86_64LiveProcess::X86_64LiveProcess(LiveProcessParams *params, mmap_start = mmap_end = (Addr)0x2aaaaaaab000ULL; } +void +I386LiveProcess::syscall(int64_t callnum, ThreadContext *tc) +{ + Addr eip = tc->readPC(); + if (eip >= vsyscallPage.base && + eip < vsyscallPage.base + vsyscallPage.size) { + tc->setNextPC(vsyscallPage.base + vsyscallPage.vsysexitOffset); + } + X86LiveProcess::syscall(callnum, tc); +} + + I386LiveProcess::I386LiveProcess(LiveProcessParams *params, ObjectFile *objFile, SyscallDesc *_syscallDescs, int _numSyscallDescs) : X86LiveProcess(params, objFile, _syscallDescs, _numSyscallDescs) { - stack_base = (Addr)0xffffe000ULL; + _gdtStart = 0x100000000; + _gdtSize = VMPageSize; + + vsyscallPage.base = 0xffffe000ULL; + vsyscallPage.size = VMPageSize; + vsyscallPage.vsyscallOffset = 0x400; + vsyscallPage.vsysexitOffset = 0x410; + + stack_base = vsyscallPage.base; // Set pointer for next thread stack. Reserve 8M for main stack. next_thread_stack_base = stack_base - (8 * 1024 * 1024); @@ -255,8 +275,6 @@ I386LiveProcess::startup() * Set up a GDT for this process. The whole GDT wouldn't really be for * this process, but the only parts we care about are. */ - _gdtStart = stack_base; - _gdtSize = VMPageSize; pTable->allocate(_gdtStart, _gdtSize); uint64_t zero = 0; assert(_gdtSize % sizeof(zero) == 0); @@ -265,6 +283,27 @@ I386LiveProcess::startup() initVirtMem->write(gdtCurrent, zero); } + // Set up the vsyscall page for this process. + pTable->allocate(vsyscallPage.base, vsyscallPage.size); + uint8_t vsyscallBlob[] = { + 0x51, // push %ecx + 0x52, // push %edp + 0x55, // push %ebp + 0x89, 0xe5, // mov %esp, %ebp + 0x0f, 0x34 // sysenter + }; + initVirtMem->writeBlob(vsyscallPage.base + vsyscallPage.vsyscallOffset, + vsyscallBlob, sizeof(vsyscallBlob)); + + uint8_t vsysexitBlob[] = { + 0x5d, // pop %ebp + 0x5a, // pop %edx + 0x59, // pop %ecx + 0xc3 // ret + }; + initVirtMem->writeBlob(vsyscallPage.base + vsyscallPage.vsysexitOffset, + vsysexitBlob, sizeof(vsysexitBlob)); + for (int i = 0; i < contextIds.size(); i++) { ThreadContext * tc = system->getThreadContext(contextIds[i]); @@ -332,12 +371,13 @@ I386LiveProcess::startup() template void -X86LiveProcess::argsInit(int pageSize) +X86LiveProcess::argsInit(int pageSize, + std::vector > extraAuxvs) { int intSize = sizeof(IntType); typedef AuxVector auxv_t; - std::vector auxv; + std::vector auxv = extraAuxvs; string filename; if(argv.size() < 1) @@ -608,13 +648,19 @@ X86LiveProcess::argsInit(int pageSize) void X86_64LiveProcess::argsInit(int intSize, int pageSize) { - X86LiveProcess::argsInit(pageSize); + std::vector > extraAuxvs; + X86LiveProcess::argsInit(pageSize, extraAuxvs); } void I386LiveProcess::argsInit(int intSize, int pageSize) { - X86LiveProcess::argsInit(pageSize); + std::vector > extraAuxvs; + //Tell the binary where the vsyscall part of the vsyscall page is. + extraAuxvs.push_back(AuxVector(0x20, + vsyscallPage.base + vsyscallPage.vsyscallOffset)); + extraAuxvs.push_back(AuxVector(0x21, vsyscallPage.base)); + X86LiveProcess::argsInit(pageSize, extraAuxvs); } void diff --git a/src/arch/x86/process.hh b/src/arch/x86/process.hh index 2d72d3fd0..cd6d99e66 100644 --- a/src/arch/x86/process.hh +++ b/src/arch/x86/process.hh @@ -80,7 +80,8 @@ namespace X86ISA SyscallDesc *_syscallDescs, int _numSyscallDescs); template - void argsInit(int pageSize); + void argsInit(int pageSize, + std::vector > extraAuxvs); public: Addr gdtStart() @@ -114,10 +115,21 @@ namespace X86ISA I386LiveProcess(LiveProcessParams *params, ObjectFile *objFile, SyscallDesc *_syscallDescs, int _numSyscallDescs); + class VSyscallPage + { + public: + Addr base; + Addr size; + Addr vsyscallOffset; + Addr vsysexitOffset; + }; + VSyscallPage vsyscallPage; + public: void argsInit(int intSize, int pageSize); void startup(); + void syscall(int64_t callnum, ThreadContext *tc); X86ISA::IntReg getSyscallArg(ThreadContext *tc, int i); void setSyscallArg(ThreadContext *tc, int i, X86ISA::IntReg val); }; -- cgit v1.2.3 From aa51c01d697124fac654b3e87a99bb2d613cae72 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:26:01 -0800 Subject: X86: Set address size to 64 bits when generating addresses internally. --- .../insts/general_purpose/data_transfer/move.py | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py index dded94968..60c046d04 100644 --- a/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py +++ b/src/arch/x86/isa/insts/general_purpose/data_transfer/move.py @@ -251,10 +251,10 @@ def macroop MOV_S_R { andi t2, regm, 0xF8, dataSize=8 andi t0, regm, 0x4, flags=(EZF,), dataSize=2 br label("globalDescriptor"), flags=(CEZF,) - ld t3, tsl, [1, t0, t2], dataSize=8 + ld t3, tsl, [1, t0, t2], dataSize=8, addressSize=8 br label("processDescriptor") globalDescriptor: - ld t3, tsg, [1, t0, t2], dataSize=8 + ld t3, tsg, [1, t0, t2], dataSize=8, addressSize=8 processDescriptor: chks regm, t3, dataSize=8 wrdl reg, t3, regm @@ -268,10 +268,10 @@ def macroop MOV_S_M { andi t2, t1, 0xF8, dataSize=8 andi t0, t1, 0x4, flags=(EZF,), dataSize=2 br label("globalDescriptor"), flags=(CEZF,) - ld t3, tsl, [1, t0, t2], dataSize=8 + ld t3, tsl, [1, t0, t2], dataSize=8, addressSize=8 br label("processDescriptor") globalDescriptor: - ld t3, tsg, [1, t0, t2], dataSize=8 + ld t3, tsg, [1, t0, t2], dataSize=8, addressSize=8 processDescriptor: chks t1, t3, dataSize=8 wrdl reg, t3, t1 @@ -286,10 +286,10 @@ def macroop MOV_S_P { andi t2, t1, 0xF8, dataSize=8 andi t0, t1, 0x4, flags=(EZF,), dataSize=2 br label("globalDescriptor"), flags=(CEZF,) - ld t3, tsl, [1, t0, t2], dataSize=8 + ld t3, tsl, [1, t0, t2], dataSize=8, addressSize=8 br label("processDescriptor") globalDescriptor: - ld t3, tsg, [1, t0, t2], dataSize=8 + ld t3, tsg, [1, t0, t2], dataSize=8, addressSize=8 processDescriptor: chks t1, t3, dataSize=8 wrdl reg, t3, t1 @@ -302,10 +302,10 @@ def macroop MOVSS_S_R { andi t2, regm, 0xF8, dataSize=8 andi t0, regm, 0x4, flags=(EZF,), dataSize=2 br label("globalDescriptor"), flags=(CEZF,) - ld t3, tsl, [1, t0, t2], dataSize=8 + ld t3, tsl, [1, t0, t2], dataSize=8, addressSize=8 br label("processDescriptor") globalDescriptor: - ld t3, tsg, [1, t0, t2], dataSize=8 + ld t3, tsg, [1, t0, t2], dataSize=8, addressSize=8 processDescriptor: chks regm, t3, SSCheck, dataSize=8 wrdl reg, t3, regm @@ -319,10 +319,10 @@ def macroop MOVSS_S_M { andi t2, t1, 0xF8, dataSize=8 andi t0, t1, 0x4, flags=(EZF,), dataSize=2 br label("globalDescriptor"), flags=(CEZF,) - ld t3, tsl, [1, t0, t2], dataSize=8 + ld t3, tsl, [1, t0, t2], dataSize=8, addressSize=8 br label("processDescriptor") globalDescriptor: - ld t3, tsg, [1, t0, t2], dataSize=8 + ld t3, tsg, [1, t0, t2], dataSize=8, addressSize=8 processDescriptor: chks t1, t3, SSCheck, dataSize=8 wrdl reg, t3, t1 @@ -337,10 +337,10 @@ def macroop MOVSS_S_P { andi t2, t1, 0xF8, dataSize=8 andi t0, t1, 0x4, flags=(EZF,), dataSize=2 br label("globalDescriptor"), flags=(CEZF,) - ld t3, tsl, [1, t0, t2], dataSize=8 + ld t3, tsl, [1, t0, t2], dataSize=8, addressSize=8 br label("processDescriptor") globalDescriptor: - ld t3, tsg, [1, t0, t2], dataSize=8 + ld t3, tsg, [1, t0, t2], dataSize=8, addressSize=8 processDescriptor: chks t1, t3, SSCheck, dataSize=8 wrdl reg, t3, t1 -- cgit v1.2.3 From 27b751ec46e59166867cedbf6da3ee19453671bd Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:26:09 -0800 Subject: X86: Don't treat the REX prefixes as prefixes in 32 bit modes. These are inc/dec instructions. --- src/arch/x86/predecoder.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/predecoder.cc b/src/arch/x86/predecoder.cc index 9d60089e3..620ab89ea 100644 --- a/src/arch/x86/predecoder.cc +++ b/src/arch/x86/predecoder.cc @@ -136,7 +136,10 @@ namespace X86ISA { uint8_t prefix = Prefixes[nextByte]; State nextState = PrefixState; - if(prefix) + // REX prefixes are only recognized in 64 bit mode. + if (prefix == RexPrefix && emi.mode.submode != SixtyFourBitMode) + prefix = 0; + if (prefix) consumeByte(); switch(prefix) { -- cgit v1.2.3 From 2fe87e62ba2bf51dfc773dd6fdb2bd1fdb09e20b Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:26:17 -0800 Subject: X86: Add a structure to allow mapping between the host and guest fstat formats. --- src/arch/x86/linux/linux.hh | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src/arch') diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh index c6fe28318..c2941c769 100644 --- a/src/arch/x86/linux/linux.hh +++ b/src/arch/x86/linux/linux.hh @@ -117,6 +117,28 @@ class X86Linux32 : public Linux { public: + typedef struct { + uint64_t st_dev; + uint8_t __pad0[4]; + uint32_t __st_ino; + uint32_t st_mode; + uint32_t st_nlink; + uint32_t st_uid; + uint32_t st_gid; + uint64_t st_rdev; + int64_t st_size; + uint8_t __pad3[4]; + uint32_t st_blksize; + uint64_t st_blocks; + uint32_t st_atimeX; + uint32_t st_atime_nsec; + uint32_t st_mtimeX; + uint32_t st_mtime_nsec; + uint32_t st_ctimeX; + uint32_t st_ctime_nsec; + uint64_t st_ino; + } tgt_stat64; + static OpenFlagTransTable openFlagTable[]; static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY -- cgit v1.2.3 From b36f28472d4e28263f4d2e3f6b3e88c9fa350ca1 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:26:26 -0800 Subject: X86: Implement shrd. --- src/arch/x86/isa/decoder/two_byte_opcodes.isa | 2 +- .../general_purpose/rotate_and_shift/shift.py | 35 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index c3fb5c19d..1ee62142a 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -830,7 +830,7 @@ 0x1: pop_gs(); 0x2: rsm_smm(); 0x3: Inst::BTS(Ev,Gv); - 0x4: shrd_Ev_Gv_Ib(); + 0x4: Inst::SHRD(Ev,Gv,Ib); 0x5: shrd_Ev_Gv_rCl(); //0x6: group16(); 0x6: decode MODRM_REG { diff --git a/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py b/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py index 138082eb2..caaeca974 100644 --- a/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py +++ b/src/arch/x86/isa/insts/general_purpose/rotate_and_shift/shift.py @@ -174,6 +174,41 @@ def macroop SHR_P_R st t1, seg, riprel, disp }; +# SHRD will not set OF correctly when the shift count is 1. +def macroop SHRD_R_R_I +{ + srli t1, reg, imm, flags=(CF,) + rori t2, regm, imm + srli t3, regm, imm + xor t2, t2, t3 + or reg, t1, t2 +}; + +# SHRD will not set OF correctly when the shift count is 1. +def macroop SHRD_M_R_I +{ + ldst t1, seg, sib, disp + srli t1, t1, imm, flags=(CF,) + rori t2, reg, imm + srli t3, reg, imm + xor t2, t2, t3 + or t1, t1, t2 + st t1, seg, sib, disp +}; + +# SHRD will not set OF correctly when the shift count is 1. +def macroop SHRD_P_R_I +{ + rdip t7 + ldst t1, seg, riprel, disp + srli t1, t1, imm, flags=(CF,) + rori t2, reg, imm + srli t3, reg, imm + xor t2, t2, t3 + or t1, t1, t2 + st t1, seg, riprel, disp +}; + def macroop SAR_R_I { srai reg, reg, imm, flags=(CF,OF,SF,ZF,PF) -- cgit v1.2.3 From 9265b3d598b5c394ed3f0f79affba7e64b171dc6 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:26:32 -0800 Subject: X86: Install the 32 bit write system call. --- src/arch/x86/linux/syscalls.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index 7969f2e41..ce4726634 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -508,7 +508,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 1 */ SyscallDesc("exit", unimplementedFunc), /* 2 */ SyscallDesc("fork", unimplementedFunc), /* 3 */ SyscallDesc("read", unimplementedFunc), - /* 4 */ SyscallDesc("write", unimplementedFunc), + /* 4 */ SyscallDesc("write", writeFunc), /* 5 */ SyscallDesc("open", openFunc), /* 6 */ SyscallDesc("close", unimplementedFunc), /* 7 */ SyscallDesc("waitpid", unimplementedFunc), -- cgit v1.2.3 From b69a9ad45a15e84a6422f308df5b6806da80e93a Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 27 Feb 2009 09:26:41 -0800 Subject: X86: Install the exit system call. --- src/arch/x86/linux/syscalls.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/arch') diff --git a/src/arch/x86/linux/syscalls.cc b/src/arch/x86/linux/syscalls.cc index ce4726634..09235ec94 100644 --- a/src/arch/x86/linux/syscalls.cc +++ b/src/arch/x86/linux/syscalls.cc @@ -756,7 +756,7 @@ SyscallDesc I386LinuxProcess::syscallDescs[] = { /* 249 */ SyscallDesc("io_cancel", unimplementedFunc), /* 250 */ SyscallDesc("fadvise64", unimplementedFunc), /* 251 */ SyscallDesc("unused", unimplementedFunc), - /* 252 */ SyscallDesc("exit_group", unimplementedFunc), + /* 252 */ SyscallDesc("exit_group", exitFunc), /* 253 */ SyscallDesc("lookup_dcookie", unimplementedFunc), /* 254 */ SyscallDesc("epoll_create", unimplementedFunc), /* 255 */ SyscallDesc("epoll_ctl", unimplementedFunc), -- cgit v1.2.3 From 4523741c1c72ef954410ccb0aa7782b28be3441b Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Fri, 27 Feb 2009 17:29:58 -0800 Subject: quell gcc 4.3 warning --- src/arch/x86/tlb.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 47a2eb37e..3fec4c7da 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -590,8 +590,8 @@ TLB::translate(RequestPtr req, ThreadContext *tc, // address size is 64 bits, overridable to 32. int size = 32; bool sizeOverride = (flags & (AddrSizeFlagBit << FlagShift)); - if (csAttr.defaultSize && sizeOverride || - !csAttr.defaultSize && !sizeOverride) + if ((csAttr.defaultSize && sizeOverride) || + (!csAttr.defaultSize && !sizeOverride)) size = 16; Addr offset = bits(vaddr - base, size-1, 0); Addr endOffset = offset + req->getSize() - 1; @@ -647,8 +647,8 @@ TLB::translate(RequestPtr req, ThreadContext *tc, // Do paging protection checks. bool inUser = (csAttr.dpl == 3 && !(flags & (CPL0FlagBit << FlagShift))); - if (inUser && !entry->user || - write && !entry->writable) { + if ((inUser && !entry->user) || + (write && !entry->writable)) { // The page must have been present to get into the TLB in // the first place. We'll assume the reserved bits are // fine even though we're not checking them. -- cgit v1.2.3 From 307905095caaa277e8ccbd58f095381d79b0c402 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Sat, 28 Feb 2009 20:14:22 -0500 Subject: Fix Num_Syscall_Descs check bug in non-x86 ISAs. (See cset d35d2b28df38 for x86 fix.) --- src/arch/alpha/linux/process.cc | 2 +- src/arch/mips/linux/process.cc | 2 +- src/arch/sparc/linux/process.cc | 4 ++-- src/arch/sparc/solaris/process.cc | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc index 1e4f75790..aeff9fbed 100644 --- a/src/arch/alpha/linux/process.cc +++ b/src/arch/alpha/linux/process.cc @@ -579,7 +579,7 @@ AlphaLinuxProcess::AlphaLinuxProcess(LiveProcessParams * params, SyscallDesc* AlphaLinuxProcess::getDesc(int callnum) { - if (callnum < 0 || callnum > Num_Syscall_Descs) + if (callnum < 0 || callnum >= Num_Syscall_Descs) return NULL; return &syscallDescs[callnum]; } diff --git a/src/arch/mips/linux/process.cc b/src/arch/mips/linux/process.cc index dc3b84ced..24e71305a 100644 --- a/src/arch/mips/linux/process.cc +++ b/src/arch/mips/linux/process.cc @@ -425,7 +425,7 @@ MipsLinuxProcess::getDesc(int callnum) //MIPS32 syscalls are in the range of 4000 - 4999 int m5_sys_idx = callnum - 4000; - if (m5_sys_idx < 0 || m5_sys_idx > Num_Syscall_Descs) + if (m5_sys_idx < 0 || m5_sys_idx >= Num_Syscall_Descs) return NULL; return &syscallDescs[m5_sys_idx]; diff --git a/src/arch/sparc/linux/process.cc b/src/arch/sparc/linux/process.cc index f4ec28c00..2078c1dce 100644 --- a/src/arch/sparc/linux/process.cc +++ b/src/arch/sparc/linux/process.cc @@ -47,7 +47,7 @@ using namespace SparcISA; SyscallDesc* SparcLinuxProcess::getDesc(int callnum) { - if (callnum < 0 || callnum > Num_Syscall_Descs) + if (callnum < 0 || callnum >= Num_Syscall_Descs) return NULL; return &syscallDescs[callnum]; } @@ -55,7 +55,7 @@ SparcLinuxProcess::getDesc(int callnum) SyscallDesc* SparcLinuxProcess::getDesc32(int callnum) { - if (callnum < 0 || callnum > Num_Syscall32_Descs) + if (callnum < 0 || callnum >= Num_Syscall32_Descs) return NULL; return &syscall32Descs[callnum]; } diff --git a/src/arch/sparc/solaris/process.cc b/src/arch/sparc/solaris/process.cc index 1a4940b59..22924736b 100644 --- a/src/arch/sparc/solaris/process.cc +++ b/src/arch/sparc/solaris/process.cc @@ -336,7 +336,7 @@ SparcSolarisProcess::SparcSolarisProcess(LiveProcessParams * params, SyscallDesc* SparcSolarisProcess::getDesc(int callnum) { - if (callnum < 0 || callnum > Num_Syscall_Descs) + if (callnum < 0 || callnum >= Num_Syscall_Descs) return NULL; return &syscallDescs[callnum]; } -- cgit v1.2.3 From e3d6e8882e02d607ed69108d4bc1301de9c2de56 Mon Sep 17 00:00:00 2001 From: Steve Reinhardt Date: Thu, 5 Mar 2009 17:15:31 -0800 Subject: Get rid of 'using namespace' declarations in headers. --- src/arch/alpha/linux/system.hh | 5 +---- src/arch/mips/bare_iron/system.hh | 2 -- src/arch/mips/isa_traits.hh | 2 -- src/arch/mips/linux/linux.hh | 3 --- src/arch/mips/linux/system.hh | 5 +---- src/arch/mips/mt.hh | 3 +-- src/arch/mips/regfile/misc_regfile.cc | 1 + 7 files changed, 4 insertions(+), 17 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/linux/system.hh b/src/arch/alpha/linux/system.hh index fa03736c3..3e4de7b2a 100644 --- a/src/arch/alpha/linux/system.hh +++ b/src/arch/alpha/linux/system.hh @@ -43,9 +43,6 @@ class IdleStartEvent; #include "kern/linux/events.hh" #include "params/LinuxAlphaSystem.hh" -using namespace AlphaISA; -using namespace Linux; - /** * This class contains linux specific system code (Loading, Events). * It points to objects that are the system binaries to load and patches them @@ -109,7 +106,7 @@ class LinuxAlphaSystem : public AlphaSystem * PC based event to skip the dprink() call and emulate its * functionality */ - DebugPrintkEvent *debugPrintkEvent; + Linux::DebugPrintkEvent *debugPrintkEvent; /** * Skip calculate_delay_loop() rather than waiting for this to be diff --git a/src/arch/mips/bare_iron/system.hh b/src/arch/mips/bare_iron/system.hh index ab4e02344..e593f832c 100755 --- a/src/arch/mips/bare_iron/system.hh +++ b/src/arch/mips/bare_iron/system.hh @@ -39,8 +39,6 @@ class IdleStartEvent; #include "arch/mips/system.hh" #include "params/BareIronMipsSystem.hh" -using namespace MipsISA; - /** * This class contains linux specific system code (Loading, Events). * It points to objects that are the system binaries to load and patches them diff --git a/src/arch/mips/isa_traits.hh b/src/arch/mips/isa_traits.hh index ed4ed9877..12c887132 100644 --- a/src/arch/mips/isa_traits.hh +++ b/src/arch/mips/isa_traits.hh @@ -381,6 +381,4 @@ namespace MipsISA }; -using namespace MipsISA; - #endif // __ARCH_MIPS_ISA_TRAITS_HH__ diff --git a/src/arch/mips/linux/linux.hh b/src/arch/mips/linux/linux.hh index 4667748fb..aaeba0a42 100644 --- a/src/arch/mips/linux/linux.hh +++ b/src/arch/mips/linux/linux.hh @@ -32,9 +32,6 @@ #define __ARCH_MIPS_LINUX_LINUX_HH__ #include "kern/linux/linux.hh" -#include - -using std::string; class MipsLinux : public Linux { diff --git a/src/arch/mips/linux/system.hh b/src/arch/mips/linux/system.hh index 24fb604ed..984f74694 100644 --- a/src/arch/mips/linux/system.hh +++ b/src/arch/mips/linux/system.hh @@ -43,9 +43,6 @@ class IdleStartEvent; #include "kern/linux/events.hh" #include "params/LinuxMipsSystem.hh" -using namespace MipsISA; -using namespace Linux; - /** * This class contains linux specific system code (Loading, Events). * It points to objects that are the system binaries to load and patches them @@ -112,7 +109,7 @@ class LinuxMipsSystem : public MipsSystem * PC based event to skip the dprink() call and emulate its * functionality */ - DebugPrintkEvent *debugPrintkEvent; + Linux::DebugPrintkEvent *debugPrintkEvent; /** * Skip calculate_delay_loop() rather than waiting for this to be diff --git a/src/arch/mips/mt.hh b/src/arch/mips/mt.hh index 8828a09a5..d0c333d86 100755 --- a/src/arch/mips/mt.hh +++ b/src/arch/mips/mt.hh @@ -45,7 +45,6 @@ #include "base/misc.hh" #include -using namespace std; namespace MipsISA { @@ -164,7 +163,7 @@ forkThread(TC *tc, Fault &fault, int Rd_bits, int Rs, int Rt) success = 1; } } else { - std::cerr << "Bad VPEs" << endl; + std::cerr << "Bad VPEs" << std::endl; } } diff --git a/src/arch/mips/regfile/misc_regfile.cc b/src/arch/mips/regfile/misc_regfile.cc index ea858abf0..a00bf166e 100644 --- a/src/arch/mips/regfile/misc_regfile.cc +++ b/src/arch/mips/regfile/misc_regfile.cc @@ -43,6 +43,7 @@ //#include "params/DerivO3CPU.hh" using namespace std; +using namespace MipsISA; std::string MiscRegFile::miscRegNames[NumMiscRegs] = { -- cgit v1.2.3 From cc95b5739097e31fdaa36a3ff443861969e338b1 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 5 Mar 2009 19:09:53 -0800 Subject: stats: Fix all stats usages to deal with template fixes --- src/arch/alpha/kernel_stats.hh | 12 ++++++------ src/arch/alpha/tlb.hh | 22 +++++++++++----------- src/arch/mips/tlb.hh | 16 ++++++++-------- 3 files changed, 25 insertions(+), 25 deletions(-) (limited to 'src/arch') diff --git a/src/arch/alpha/kernel_stats.hh b/src/arch/alpha/kernel_stats.hh index aab96b150..837269309 100644 --- a/src/arch/alpha/kernel_stats.hh +++ b/src/arch/alpha/kernel_stats.hh @@ -62,15 +62,15 @@ class Statistics : public ::Kernel::Statistics void changeMode(cpu_mode newmode, ThreadContext *tc); private: - Stats::Vector<> _callpal; -// Stats::Vector<> _faults; + Stats::Vector _callpal; +// Stats::Vector _faults; - Stats::Vector<> _mode; - Stats::Vector<> _modeGood; + Stats::Vector _mode; + Stats::Vector _modeGood; Stats::Formula _modeFraction; - Stats::Vector<> _modeTicks; + Stats::Vector _modeTicks; - Stats::Scalar<> _swap_context; + Stats::Scalar _swap_context; public: Statistics(System *system); diff --git a/src/arch/alpha/tlb.hh b/src/arch/alpha/tlb.hh index 877533797..643889534 100644 --- a/src/arch/alpha/tlb.hh +++ b/src/arch/alpha/tlb.hh @@ -121,9 +121,9 @@ class TLB : public BaseTLB class ITB : public TLB { protected: - mutable Stats::Scalar<> hits; - mutable Stats::Scalar<> misses; - mutable Stats::Scalar<> acv; + mutable Stats::Scalar hits; + mutable Stats::Scalar misses; + mutable Stats::Scalar acv; mutable Stats::Formula accesses; public: @@ -139,14 +139,14 @@ class ITB : public TLB class DTB : public TLB { protected: - mutable Stats::Scalar<> read_hits; - mutable Stats::Scalar<> read_misses; - mutable Stats::Scalar<> read_acv; - mutable Stats::Scalar<> read_accesses; - mutable Stats::Scalar<> write_hits; - mutable Stats::Scalar<> write_misses; - mutable Stats::Scalar<> write_acv; - mutable Stats::Scalar<> write_accesses; + mutable Stats::Scalar read_hits; + mutable Stats::Scalar read_misses; + mutable Stats::Scalar read_acv; + mutable Stats::Scalar read_accesses; + mutable Stats::Scalar write_hits; + mutable Stats::Scalar write_misses; + mutable Stats::Scalar write_acv; + mutable Stats::Scalar write_accesses; Stats::Formula hits; Stats::Formula misses; Stats::Formula acv; diff --git a/src/arch/mips/tlb.hh b/src/arch/mips/tlb.hh index 1ab9d77e5..dc0babf9a 100644 --- a/src/arch/mips/tlb.hh +++ b/src/arch/mips/tlb.hh @@ -96,14 +96,14 @@ class TLB : public BaseTLB void nextnlu() { if (++nlu >= size) nlu = 0; } MipsISA::PTE *lookup(Addr vpn, uint8_t asn) const; - mutable Stats::Scalar<> read_hits; - mutable Stats::Scalar<> read_misses; - mutable Stats::Scalar<> read_acv; - mutable Stats::Scalar<> read_accesses; - mutable Stats::Scalar<> write_hits; - mutable Stats::Scalar<> write_misses; - mutable Stats::Scalar<> write_acv; - mutable Stats::Scalar<> write_accesses; + mutable Stats::Scalar read_hits; + mutable Stats::Scalar read_misses; + mutable Stats::Scalar read_acv; + mutable Stats::Scalar read_accesses; + mutable Stats::Scalar write_hits; + mutable Stats::Scalar write_misses; + mutable Stats::Scalar write_acv; + mutable Stats::Scalar write_accesses; Stats::Formula hits; Stats::Formula misses; Stats::Formula invalids; -- cgit v1.2.3 From ac64586a99cad5aa8daf4346e1f6021764dbca1b Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Sat, 7 Mar 2009 21:34:50 -0800 Subject: build: fix compiler warnings in g++ 3.4 --- src/arch/x86/faults.hh | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/faults.hh b/src/arch/x86/faults.hh index cb1a3f18a..fe5132994 100644 --- a/src/arch/x86/faults.hh +++ b/src/arch/x86/faults.hh @@ -76,9 +76,9 @@ namespace X86ISA uint64_t errorCode; X86FaultBase(const char * _faultName, const char * _mnem, - const uint8_t _vector, uint64_t _errorCode = -1) : - faultName(_faultName), mnem(_mnem), - vector(_vector), errorCode(_errorCode) + const uint8_t _vector, uint64_t _errorCode = (uint64_t)-1) + : faultName(_faultName), mnem(_mnem), + vector(_vector), errorCode(_errorCode) { } @@ -115,8 +115,8 @@ namespace X86ISA { protected: X86Fault(const char * name, const char * mnem, - const uint8_t vector, uint64_t _errorCode = -1) : - X86FaultBase(name, mnem, vector, _errorCode) + const uint8_t vector, uint64_t _errorCode = (uint64_t)-1) + : X86FaultBase(name, mnem, vector, _errorCode) {} }; @@ -126,8 +126,8 @@ namespace X86ISA { protected: X86Trap(const char * name, const char * mnem, - const uint8_t vector, uint64_t _errorCode = -1) : - X86FaultBase(name, mnem, vector, _errorCode) + const uint8_t vector, uint64_t _errorCode = (uint64_t)-1) + : X86FaultBase(name, mnem, vector, _errorCode) {} #if FULL_SYSTEM @@ -140,8 +140,8 @@ namespace X86ISA { protected: X86Abort(const char * name, const char * mnem, - const uint8_t vector, uint64_t _errorCode = -1) : - X86FaultBase(name, mnem, vector, _errorCode) + const uint8_t vector, uint64_t _errorCode = (uint64_t)-1) + : X86FaultBase(name, mnem, vector, _errorCode) {} #if FULL_SYSTEM @@ -154,8 +154,8 @@ namespace X86ISA { protected: X86Interrupt(const char * name, const char * mnem, - const uint8_t _vector, uint64_t _errorCode = -1) : - X86FaultBase(name, mnem, _vector, _errorCode) + const uint8_t _vector, uint64_t _errorCode = (uint64_t)-1) + : X86FaultBase(name, mnem, _vector, _errorCode) {} }; -- cgit v1.2.3