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

Subversion Repositories riscv_vhdl

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /riscv_vhdl/trunk/debugger/src/common
    from Rev 4 to Rev 5
    Reverse comparison

Rev 4 → Rev 5

/coreservices/icpu_hc08.h
0,0 → 1,86
/**
* @file
* @copyright Copyright 2017 GNSS Sensor Ltd. All right reserved.
* @author Sergey Khabarov - sergeykhbr@gmail.com
* @brief CPU HC08 specific interface.
*/
 
#ifndef __DEBUGGER_COMMON_CORESERVICES_ICPU_HC08_H__
#define __DEBUGGER_COMMON_CORESERVICES_ICPU_HC08_H__
 
#include <inttypes.h>
#include <iface.h>
 
namespace debugger {
 
static const char *const IFACE_CPU_HC08 = "ICpuHC08";
 
enum ERegNames {
Reg_A, // 0
Reg_HX, // 1
Reg_SP, // 2
Reg_CCR, // 3
Reg_PPAGE, // 4
Reg_ClkHz, // 5
Reg_rsrv6, // 6
Reg_rsrv7,
Reg_rsrv8,
Reg_rsrv9,
Reg_rsrv10,
Reg_rsrv11,
Reg_rsrv12,
Reg_rsrv13,
Reg_rsrv14,
Reg_rsrv15,
Reg_rsrv16,
Reg_rsrv17,
Reg_rsrv18,
Reg_rsrv19,
Reg_rsrv20,
Reg_rsrv21,
Reg_rsrv22,
Reg_rsrv23,
Reg_rsrv24,
Reg_rsrv25,
Reg_rsrv26,
Reg_rsrv27,
Reg_rsrv28,
Reg_rsrv29,
Reg_rsrv30,
Reg_rsrv31,
Reg_Total
};
 
/** Signal types */
enum EResetType {
RESET_Unused0,
RESET_LVI, // Low-voltage inhibit Reset Bit
RESET_Unused2,
RESET_ILAD, // Illegal Address Reset Bit
RESET_ILOP, // Illegal Opcode Reset Bit
RESET_COP, // Compute Operating Properly Reset Bit
RESET_PIN, // External Reset Bit (nRST)
RESET_PON, // POWER-on Reset Bit
};
 
class ICpuHC08 : public IFace {
public:
ICpuHC08() : IFace(IFACE_CPU_HC08) {}
 
/** Fast access to memory mapped registers */
virtual Reg64Type *getpRegs() = 0;
 
/** External IRQ line status (need for BIH, BIL instructions) */
virtual bool getIRQ() = 0;
 
/** Update COP watchdog settings */
virtual void updateCOP() = 0;
 
/** Reset sequence has ben writen */
virtual void resetCOP() = 0;
virtual void vectorUpdated() = 0;
};
 
} // namespace debugger
 
#endif // __DEBUGGER_COMMON_CORESERVICES_ICPU_HC08_H__
coreservices/icpu_hc08.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property Index: coreservices/icpuarm.h =================================================================== --- coreservices/icpuarm.h (nonexistent) +++ coreservices/icpuarm.h (revision 5) @@ -0,0 +1,75 @@ +/* + * Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DEBUGGER_SRC_COMMON_CORESERVICES_ICPUARM_H__ +#define __DEBUGGER_SRC_COMMON_CORESERVICES_ICPUARM_H__ + +#include "iface.h" +#include + +namespace debugger { + +static const char *const IFACE_CPU_ARM = "ICpuArm"; + +/** Signal types */ +//static const int CPU_SIGNAL_RESET = 0; +//static const int CPU_SIGNAL_EXT_IRQ = 1; + +enum EInstructionModes { + ARM_mode, + THUMB_mode, + Jazelle_mode, + InstrModes_Total = 4 +}; + +enum ECoreModes { + User_mode = 0x10, + FIQ_mode = 0x11, + IRQ_mode = 0x12, + Supervisor_mode = 0x13, + Abort_mode = 0x17, + Undefined_mode = 0x1B, + System_mode = 0x1F, + CoreModes_Total = 32 +}; + +class ICpuArm : public IFace { + public: + ICpuArm() : IFace(IFACE_CPU_ARM) {} + + virtual void setInstrMode(EInstructionModes mode) {} + virtual EInstructionModes getInstrMode() { return ARM_mode; } + + /** Zero flag */ + virtual uint32_t getZ() = 0; + virtual void setZ(uint32_t z) = 0; + + /** Unsigned higer or same (carry flag) */ + virtual uint32_t getC() = 0; + virtual void setC(uint32_t c) = 0; + + /** Negative flag */ + virtual uint32_t getN() = 0; + virtual void setN(uint32_t n) = 0; + + /** Overflow flag */ + virtual uint32_t getV() = 0; + virtual void setV(uint32_t v) = 0; +}; + +} // namespace debugger + +#endif // __DEBUGGER_SRC_COMMON_CORESERVICES_ICPUARM_H__
coreservices/icpuarm.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property Index: coreservices/icpufunctional.h =================================================================== --- coreservices/icpufunctional.h (nonexistent) +++ coreservices/icpufunctional.h (revision 5) @@ -0,0 +1,79 @@ +/** + * @file + * @copyright Copyright 2017 GNSS Sensor Ltd. All right reserved. + * @author Sergey Khabarov - sergeykhbr@gmail.com + * @brief Functional CPU model interface. + */ + +#ifndef __DEBUGGER_COMMON_CORESERVICES_ICPUFUNCTIONAL_H__ +#define __DEBUGGER_COMMON_CORESERVICES_ICPUFUNCTIONAL_H__ + +#include +#include +#include +#include "coreservices/imemop.h" + +namespace debugger { + +static const char *const IFACE_INSTRUCTION = "IInstruction"; + +class IInstruction : public IFace { + public: + IInstruction() : IFace(IFACE_INSTRUCTION) {} + + virtual const char *name() = 0; + /** Return instruction size */ + virtual int exec(Reg64Type *payload) = 0; +}; + +class GenericInstruction : public IInstruction { + public: + GenericInstruction() : IInstruction() {} +}; + +enum EEndianessType { + LittleEndian, + BigEndian, +}; + +static const char *const IFACE_CPU_FUNCTIONAL = "ICpuFunctional"; + +class ICpuFunctional : public IFace { + public: + ICpuFunctional() : IFace(IFACE_CPU_FUNCTIONAL) {} + + virtual void raiseSoftwareIrq() = 0; + virtual uint64_t getPC() = 0; + virtual void setBranch(uint64_t npc) = 0; + virtual void pushStackTrace() = 0; + virtual void popStackTrace() = 0; + virtual uint64_t getPrvLevel() = 0; + virtual void setPrvLevel(uint64_t lvl) = 0; + virtual void dma_memop(Axi4TransactionType *tr) = 0; + virtual bool isOn() = 0; + virtual bool isHalt() = 0; + virtual bool isSwBreakpoint() = 0; + virtual bool isHwBreakpoint() = 0; + virtual void go() = 0; + virtual void halt(const char *descr) = 0; + virtual void step() = 0; + virtual void addHwBreakpoint(uint64_t addr) = 0; + virtual void removeHwBreakpoint(uint64_t addr) = 0; + virtual void skipBreakpoint() = 0; + + protected: + virtual uint64_t getResetAddress() = 0; + virtual uint64_t getIrqAddress(int idx) = 0; + virtual EEndianessType endianess() = 0; + virtual GenericInstruction *decodeInstruction(Reg64Type *cache) = 0; + virtual void generateIllegalOpcode() = 0; + virtual void handleTrap() = 0; + /** Tack Registers changes during execution */ + virtual void trackContextStart() = 0; + /** Stop tracking and write trace file */ + virtual void trackContextEnd() = 0; +}; + +} // namespace debugger + +#endif // __DEBUGGER_COMMON_CORESERVICES_ICPUFUNCTIONAL_H__
coreservices/icpufunctional.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property Index: coreservices/icpugen.h =================================================================== --- coreservices/icpugen.h (nonexistent) +++ coreservices/icpugen.h (revision 5) @@ -0,0 +1,50 @@ +/** + * @file + * @copyright Copyright 2017 GNSS Sensor Ltd. All right reserved. + * @author Sergey Khabarov - sergeykhbr@gmail.com + * @brief Generic CPU simulating interface. + */ + +#ifndef __DEBUGGER_COMMON_CORESERVICES_ICPUGEN_H__ +#define __DEBUGGER_COMMON_CORESERVICES_ICPUGEN_H__ + +#include +#include +#include "coreservices/imemop.h" + +namespace debugger { + +static const char *const IFACE_CPU_GENERIC = "ICpuGeneric"; +static const uint64_t REG_INVALID = ~0; + +struct DebugPortTransactionType { + bool write; + uint8_t region; + uint16_t addr; + uint32_t bytes; + uint64_t wdata; + uint64_t rdata; +}; + +static const char *const IFACE_DBG_NB_RESPONSE = "IDbgNbResponse"; + +class IDbgNbResponse : public IFace { + public: + IDbgNbResponse() : IFace(IFACE_DBG_NB_RESPONSE) {} + + virtual void nb_response_debug_port(DebugPortTransactionType *trans) = 0; +}; + +class ICpuGeneric : public IFace { + public: + ICpuGeneric() : IFace(IFACE_CPU_GENERIC) {} + + virtual void raiseSignal(int idx) = 0; + virtual void lowerSignal(int idx) = 0; + virtual void nb_transport_debug_port(DebugPortTransactionType *trans, + IDbgNbResponse *cb) = 0; +}; + +} // namespace debugger + +#endif // __DEBUGGER_COMMON_CORESERVICES_ICPUGEN_H__
coreservices/icpugen.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property Index: coreservices/idisplay.h =================================================================== --- coreservices/idisplay.h (nonexistent) +++ coreservices/idisplay.h (revision 5) @@ -0,0 +1,40 @@ +/** + * @file + * @copyright Copyright 2017 GNSS Sensor Ltd. All right reserved. + * @author Sergey Khabarov - sergeykhbr@gmail.com + * @brief Dismplay Simulation interface. + */ + +#ifndef __DEBUGGER_PLUGIN_IDISPLAY_H__ +#define __DEBUGGER_PLUGIN_IDISPLAY_H__ + +#include +#include + +namespace debugger { + +static const char *const IFACE_DISPLAY = "IDisplay"; + +class IDisplay : public IFace { + public: + IDisplay() : IFace(IFACE_DISPLAY) {} + + virtual void initFrame() = 0; + virtual void setFramePixel(int x, int y, uint32_t rgb) = 0; + virtual void updateFrame() = 0; +}; + +static const char *const IFACE_LED_CONTROLLER = "ILedController"; + +class ILedController : public IFace { + public: + ILedController() : IFace(IFACE_LED_CONTROLLER) {} + + virtual void getResolution(int *width, int *height) = 0; + virtual void registerDisplay(IDisplay *led) = 0; + virtual void unregisterDisplay(IDisplay *led) = 0; +}; + +} // namespace debugger + +#endif // __DEBUGGER_PLUGIN_IDISPLAY_H__
coreservices/idisplay.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property Index: coreservices/idsugen.h =================================================================== --- coreservices/idsugen.h (nonexistent) +++ coreservices/idsugen.h (revision 5) @@ -0,0 +1,29 @@ +/** + * @file + * @copyright Copyright 2017 GNSS Sensor Ltd. All right reserved. + * @author Sergey Khabarov - sergeykhbr@gmail.com + * @brief Generic Debug Support Unit simulating interface. + */ + +#ifndef __DEBUGGER_COMMON_CORESERVICES_IDSUGEN_H__ +#define __DEBUGGER_COMMON_CORESERVICES_IDSUGEN_H__ + +#include +#include + +namespace debugger { + +static const char *const IFACE_DSU_GENERIC = "IDsuGeneric"; + +class IDsuGeneric : public IFace { + public: + IDsuGeneric() : IFace(IFACE_DSU_GENERIC) {} + + /** Bus utilization statistic methods */ + virtual void incrementRdAccess(int mst_id) = 0; + virtual void incrementWrAccess(int mst_id) = 0; +}; + +} // namespace debugger + +#endif // __DEBUGGER_COMMON_CORESERVICES_ICPUGEN_H__
coreservices/idsugen.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property Index: coreservices/iencoder.h =================================================================== --- coreservices/iencoder.h (nonexistent) +++ coreservices/iencoder.h (revision 5) @@ -0,0 +1,31 @@ +/** + * @file + * @copyright Copyright 2017 GNSS Sensor Ltd. All right reserved. + * @author Sergey Khabarov - sergeykhbr@gmail.com + * @brief Optical Encoder interface. + */ + +#ifndef __DEBUGGER_COMMON_CORESERVICES_IENCODER_H__ +#define __DEBUGGER_COMMON_CORESERVICES_IENCODER_H__ + +#include +#include + +namespace debugger { + +static const char *const IFACE_ENCODER = "IEncoder"; + +class IEncoder : public IFace { + public: + IEncoder() : IFace(IFACE_ENCODER) {} + + virtual void rotateOn(int steps) = 0; + virtual uint8_t getEncoderState() = 0; + virtual double getAngleDegrees() = 0; + virtual double getHoles() = 0; + virtual double getPeriods() = 0; +}; + +} // namespace debugger + +#endif // __DEBUGGER_COMMON_CORESERVICES_IENCODER_H__
coreservices/iencoder.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property Index: coreservices/ii2c.h =================================================================== --- coreservices/ii2c.h (nonexistent) +++ coreservices/ii2c.h (revision 5) @@ -0,0 +1,46 @@ +/** + * @file + * @copyright Copyright 2017 GNSS Sensor Ltd. All right reserved. + * @author Sergey Khabarov - sergeykhbr@gmail.com + * @brief I2C interface description. + */ + +#ifndef __DEBUGGER_COMMON_CORESERVICES_II2C_H__ +#define __DEBUGGER_COMMON_CORESERVICES_II2C_H__ + +#include +#include + +namespace debugger { + +enum EStatusI2C { + I2C_ACK = 0, + I2C_NACK = 1 +}; + +static const char *const IFACE_I2C_MASTER = "IMasterI2C"; + +class IMasterI2C : public IFace { + public: + IMasterI2C() : IFace(IFACE_I2C_MASTER) {} + + virtual void registerI2CListener(IFace *iface) = 0; + virtual void unregisterI2CListener(IFace *iface) = 0; +}; + +static const char *const IFACE_I2C_SLAVE = "ISlaveI2C"; + +class ISlaveI2C : public IFace { + public: + ISlaveI2C() : IFace(IFACE_I2C_SLAVE) {} + + virtual uint8_t getPhysAddress() = 0; + virtual uint8_t getAddressLen() = 0; + virtual void setAddress(uint32_t addr) = 0; + virtual EStatusI2C writeNext(uint8_t byte) = 0; + virtual EStatusI2C readNext(uint8_t *byte) = 0; +}; + +} // namespace debugger + +#endif // __DEBUGGER_COMMON_CORESERVICES_II2C_H__
coreservices/ii2c.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property Index: coreservices/iioport.h =================================================================== --- coreservices/iioport.h (nonexistent) +++ coreservices/iioport.h (revision 5) @@ -0,0 +1,38 @@ +/** + * @file + * @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved. + * @author Sergey Khabarov - sergeykhbr@gmail.com + * @brief IO-port interface declaration. + */ + +#ifndef __DEBUGGER_COMMON_CORESERVICES_IIOPORT_H__ +#define __DEBUGGER_COMMON_CORESERVICES_IIOPORT_H__ + +#include + +namespace debugger { + +static const char *IFACE_IOPORT = "IIOPort"; + +class IIOPort : public IFace { + public: + IIOPort() : IFace(IFACE_IOPORT) {} + + virtual void registerPortListener(IFace *listener) = 0; + virtual void unregisterPortListener(IFace *listener) = 0; +}; + +static const char *IFACE_IOPORT_LISTENER = "IIOPortListener"; + +class IIOPortListener : public IFace { + public: + IIOPortListener() : IFace(IFACE_IOPORT_LISTENER) {} + + virtual void readData(uint8_t *val, uint8_t mask) = 0; + virtual void writeData(uint8_t val, uint8_t mask) = 0; + virtual void latch() = 0; +}; + +} // namespace debugger + +#endif // __DEBUGGER_COMMON_CORESERVICES_IIOPORT_H__
coreservices/iioport.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property Index: coreservices/ikeyboard.h =================================================================== --- coreservices/ikeyboard.h (nonexistent) +++ coreservices/ikeyboard.h (revision 5) @@ -0,0 +1,28 @@ +/** + * @file + * @copyright Copyright 2017 GNSS Sensor Ltd. All right reserved. + * @author Sergey Khabarov - sergeykhbr@gmail.com + * @brief Keyboard interface declaration. + */ + +#ifndef __DEBUGGER_COMMON_CORESERVICES_IKEYBOARD_H__ +#define __DEBUGGER_COMMON_CORESERVICES_IKEYBOARD_H__ + +#include +#include + +namespace debugger { + +static const char *const IFACE_KEYBOARD = "IKeyboard"; + +class IKeyboard : public IFace { + public: + IKeyboard() : IFace(IFACE_KEYBOARD) {} + + virtual void keyPress(const char *keyname) = 0; + virtual void keyRelease(const char *keyname) = 0; +}; + +} // namespace debugger + +#endif // __DEBUGGER_COMMON_CORESERVICES_IKEYBOARD_H__
coreservices/ikeyboard.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property Index: coreservices/ilink.h =================================================================== --- coreservices/ilink.h (nonexistent) +++ coreservices/ilink.h (revision 5) @@ -0,0 +1,38 @@ +/** + * @file + * @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved. + * @author Sergey Khabarov - sergeykhbr@gmail.com + * @brief Link interface declaration. + */ + +#ifndef __DEBUGGER_COMMON_CORESERVICES_ILINK_H__ +#define __DEBUGGER_COMMON_CORESERVICES_ILINK_H__ + +#include +#include +#include "irawlistener.h" + +namespace debugger { + +static const char *const IFACE_LINK = "ILink"; + +class ILink : public IFace { + public: + ILink() : IFace(IFACE_LINK) {} + + /** Get opened socket connection settings. */ + virtual void getConnectionSettings(AttributeType *settings) = 0; + + /** Setup remote host settings */ + virtual void setConnectionSettings(const AttributeType *target) = 0; + + /** Send datagram buffer. */ + virtual int sendData(const uint8_t *msg, int len) = 0; + + /** Read datagram buffer. */ + virtual int readData(const uint8_t *buf, int maxlen) = 0; +}; + +} // namespace debugger + +#endif // __DEBUGGER_COMMON_CORESERVICES_ILINK_H__
coreservices/ilink.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property Index: coreservices/immu.h =================================================================== --- coreservices/immu.h (nonexistent) +++ coreservices/immu.h (revision 5) @@ -0,0 +1,28 @@ +/** + * @file + * @copyright Copyright 2017 GNSS Sensor Ltd. All right reserved. + * @author Sergey Khabarov - sergeykhbr@gmail.com + * @brief HC08 MMU interface. + */ + +#ifndef __DEBUGGER_COMMON_CORESERVICES_IMMU_H__ +#define __DEBUGGER_COMMON_CORESERVICES_IMMU_H__ + +#include +#include + +namespace debugger { + +static const char *const IFACE_MMU = "IMMU"; + +class IMMU : public IFace { + public: + IMMU() : IFace(IFACE_MMU) {} + + virtual uint32_t get_ppage() = 0; + virtual void set_ppage(uint8_t v) = 0; +}; + +} // namespace debugger + +#endif // __DEBUGGER_COMMON_CORESERVICES_IMMU_H__
coreservices/immu.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property Index: coreservices/imotor.h =================================================================== --- coreservices/imotor.h (nonexistent) +++ coreservices/imotor.h (revision 5) @@ -0,0 +1,40 @@ +/** + * @file + * @copyright Copyright 2017 GNSS Sensor Ltd. All right reserved. + * @author Sergey Khabarov - sergeykhbr@gmail.com + * @brief Motor with sensors interface. + */ + +#ifndef __DEBUGGER_PLUGIN_IMOTOR_H__ +#define __DEBUGGER_PLUGIN_IMOTOR_H__ + +#include +#include + +namespace debugger { + +static const char *const IFACE_MOTOR = "IMotor"; + +class IMotor : public IFace { + public: + IMotor() : IFace(IFACE_MOTOR) {} + + /** 0 = motor is stopped; 1.0 = maximum rpm and enabled Breaks */ + virtual double getPowerConsumption() = 0; + + /** Backward pressure: 1.0 = 100% oclusion; 0 = no backward pressure */ + virtual double getForceResistance() = 0; + virtual void changeForceResistance(double v) = 0; + + /** value in a range 0 to length mm */ + virtual double getActuatorPos() = 0; + virtual double getActuatorMax() = 0; + + // Debug methods: + virtual double getVelocity() = 0; + virtual double getCurrent() = 0; +}; + +} // namespace debugger + +#endif // __DEBUGGER_PLUGIN_IMOTOR_H__
coreservices/imotor.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property Index: coreservices/ipll.h =================================================================== --- coreservices/ipll.h (nonexistent) +++ coreservices/ipll.h (revision 5) @@ -0,0 +1,27 @@ +/** + * @file + * @copyright Copyright 2017 GNSS Sensor Ltd. All right reserved. + * @author Sergey Khabarov - sergeykhbr@gmail.com + * @brief PLL interface. + */ + +#ifndef __DEBUGGER_COMMON_CORESERVICES_IPLL_H__ +#define __DEBUGGER_COMMON_CORESERVICES_IPLL_H__ + +#include +#include + +namespace debugger { + +static const char *const IFACE_PLL = "IPLL"; + +class IPLL : public IFace { + public: + IPLL() : IFace(IFACE_PLL) {} + + virtual uint64_t getBusClockHz() = 0; +}; + +} // namespace debugger + +#endif // __DEBUGGER_PLUGIN_IPLL_H__
coreservices/ipll.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property Index: coreservices/ireset.h =================================================================== --- coreservices/ireset.h (nonexistent) +++ coreservices/ireset.h (revision 5) @@ -0,0 +1,66 @@ +/** + * @file + * @copyright Copyright 2017 GNSS Sensor Ltd. All right reserved. + * @author Sergey Khabarov - sergeykhbr@gmail.com + * @brief Generic reset interface. + */ + +#ifndef __DEBUGGER_PLUGIN_IRESET_H__ +#define __DEBUGGER_PLUGIN_IRESET_H__ + +#include +#include +#include + +namespace debugger { + +static const char *IFACE_RESET_LISTENER = "IResetListener"; + +class IResetListener : public IFace { + public: + IResetListener() : IFace(IFACE_RESET_LISTENER) {} + + virtual void reset(bool active) = 0; +}; + +static const char *const IFACE_RESET = "IReset"; + +class IReset : public IFace { + public: + IReset() : IFace(IFACE_RESET) { + resetListeners_.make_list(0); + } + + virtual void registerResetListener(IFace *listener) { + AttributeType item; + item.make_iface(listener); + resetListeners_.add_to_list(&item); + } + + virtual void unregisterResetListener(IFace *listener) { + for (unsigned i = 0; i < resetListeners_.size(); i++) { + if (listener == resetListeners_[i].to_iface()) { + resetListeners_.remove_from_list(i); + return; + } + } + } + + void reset(bool active) { + IResetListener *l; + for (unsigned i = 0; i < resetListeners_.size(); i++) { + l = static_cast(resetListeners_[i].to_iface()); + l->reset(active); + } + } + + virtual void powerOnPressed() = 0; + virtual void powerOnReleased() = 0; + + protected: + AttributeType resetListeners_; +}; + +} // namespace debugger + +#endif // __DEBUGGER_PLUGIN_IRESET_H__
coreservices/ireset.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property Index: coreservices/isensor.h =================================================================== --- coreservices/isensor.h (nonexistent) +++ coreservices/isensor.h (revision 5) @@ -0,0 +1,31 @@ +/** + * @file + * @copyright Copyright 2017 GNSS Sensor Ltd. All right reserved. + * @author Sergey Khabarov - sergeykhbr@gmail.com + * @brief Sensor's interface. + */ + +#ifndef __DEBUGGER_PLUGIN_ISENSOR_H__ +#define __DEBUGGER_PLUGIN_ISENSOR_H__ + +#include +#include + +namespace debugger { + +static const char *const IFACE_SENSOR = "ISensor"; + +class ISensor : public IFace { + public: + ISensor() : IFace(IFACE_SENSOR) {} + + virtual void changeSensorValue(double rate) = 0; + virtual double getSensorValue() = 0; + virtual double getPhysicalValue() { + return getSensorValue(); + } +}; + +} // namespace debugger + +#endif // __DEBUGGER_PLUGIN_ISENSOR_H__
coreservices/isensor.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property Index: coreservices/isound.h =================================================================== --- coreservices/isound.h (nonexistent) +++ coreservices/isound.h (revision 5) @@ -0,0 +1,55 @@ +/** + * @file + * @copyright Copyright 2017 GNSS Sensor Ltd. All right reserved. + * @author Sergey Khabarov - sergeykhbr@gmail.com + * @brief Sound source interface with wav-format suppport. + */ + +#ifndef __DEBUGGER_COMMON_CORESERVICES_ISOUND_H__ +#define __DEBUGGER_COMMON_CORESERVICES_ISOUND_H__ + +#include +#include +#include + +namespace debugger { + +static const char *const IFACE_SOUND = "ISound"; + +static const int SOUND_CHANNELS_MAX = 2; + +struct SoundSampleType { + int chan[SOUND_CHANNELS_MAX]; +}; + +class ISound : public IFace { + public: + ISound() : IFace(IFACE_SOUND) { + soundListeners_.make_list(0); + } + + /** Update listeners with configurable bit rate 44.1 kHz for an example */ + virtual void registerSoundListener(IFace *listener) { + AttributeType item; + item.make_iface(listener); + soundListeners_.add_to_list(&item); + } + + virtual void unregisterSoundListener(IFace *listener) { + for (unsigned i = 0; i < soundListeners_.size(); i++) { + if (listener == soundListeners_[i].to_iface()) { + soundListeners_.remove_from_list(i); + return; + } + } + } + + virtual double getFreqDetectedHz() = 0; + + protected: + AttributeType soundListeners_; +}; + +} // namespace debugger + +#endif // __DEBUGGER_COMMON_CORESERVICES_ISOUND_H__
coreservices/isound.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property Index: debug/debugmap.h =================================================================== --- debug/debugmap.h (nonexistent) +++ debug/debugmap.h (revision 5) @@ -0,0 +1,35 @@ +/** + * @file + * @copyright Copyright 2017 GNSS Sensor Ltd. All right reserved. + * @author Sergey Khabarov - sergeykhbr@gmail.com + * @brief Debug Support Unit (DSU) memory map. + */ + +#ifndef __DEBUGGER_COMMON_DEBUG_DEBUGMAP_H__ +#define __DEBUGGER_COMMON_DEBUG_DEBUGMAP_H__ + +#include + +namespace debugger { + +union GenericCpuControlType { + uint64_t val; + struct { + uint64_t halt : 1; + uint64_t stepping : 1; + uint64_t sw_breakpoint : 1; + uint64_t hw_breakpoint : 1; + uint64_t core_id : 16; + uint64_t rsv2 : 12; + uint64_t istate : 2; // [33:32] icache state + uint64_t rsv3 : 2; // [35:34] + uint64_t dstate : 2; // [37:36] dcache state + uint64_t rsv4 : 2; // [39:38] + uint64_t cstate : 2; // [41:40] cachetop state + uint64_t rsv5 : 22; + } bits; +}; + +} // namespace debugger + +#endif // __DEBUGGER_COMMON_DEBUG_DEBUGMAP_H__
debug/debugmap.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property Index: debug/dsu.cpp =================================================================== --- debug/dsu.cpp (nonexistent) +++ debug/dsu.cpp (revision 5) @@ -0,0 +1,168 @@ +/** + * @file + * @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved. + * @author Sergey Khabarov - sergeykhbr@gmail.com + * @brief Debug Support Unit (DSU) functional model. + */ + +#include +#include "dsu.h" + +namespace debugger { + +DSU::DSU(const char *name) : IService(name) { + registerInterface(static_cast(this)); + registerInterface(static_cast(this)); + registerInterface(static_cast(this)); + registerAttribute("CPU", &cpu_); + registerAttribute("Bus", &bus_); + + memset(&info_, 0, sizeof(info_)); + soft_reset_ = 0x0; // Active LOW +} + +DSU::~DSU() { +} + +void DSU::postinitService() { + icpu_ = static_cast( + RISCV_get_service_iface(cpu_.to_string(), IFACE_CPU_GENERIC)); + if (!icpu_) { + RISCV_error("Can't find ICpuGeneric interface %s", cpu_.to_string()); + } + icpurst_ = static_cast( + RISCV_get_service_iface(cpu_.to_string(), IFACE_RESET_LISTENER)); + if (!icpurst_) { + RISCV_error("Can't find IResetListener interface %s", + cpu_.to_string()); + } + ibus_ = static_cast( + RISCV_get_service_iface(bus_.to_string(), IFACE_MEMORY_OPERATION)); + if (!ibus_) { + RISCV_error("Can't find IBus interface %s", bus_.to_string()); + } +} + +ETransStatus DSU::b_transport(Axi4TransactionType *trans) { + uint64_t mask = (length_.to_uint64() - 1); + uint64_t off64 = (trans->addr - getBaseAddress()) & mask; + if (!icpu_) { + trans->response = MemResp_Error; + return TRANS_ERROR; + } + uint64_t region = (off64 >> 15) & 0x3; + + if (region < 3) { + RISCV_error("b_transport() to debug port NOT SUPPORTED", NULL); + trans->response = MemResp_Error; + return TRANS_ERROR; + } + + if (trans->action == MemAction_Read) { + readLocal(off64 & 0x7fff, trans); + } else { + writeLocal(off64 & 0x7fff, trans); + } + + trans->response = MemResp_Valid; + // @todo Memory mapped registers not related to debug port + return TRANS_OK; +} + +ETransStatus DSU::nb_transport(Axi4TransactionType *trans, + IAxi4NbResponse *cb) { + uint64_t mask = (length_.to_uint64() - 1); + uint64_t off64 = (trans->addr - getBaseAddress()) & mask; + if (!icpu_) { + trans->response = MemResp_Error; + cb->nb_response(trans); + return TRANS_ERROR; + } + + nb_trans_.p_axi_trans = trans; + nb_trans_.iaxi_cb = cb; + + nb_trans_.dbg_trans.write = 0; + nb_trans_.dbg_trans.bytes = trans->xsize; + if (trans->action == MemAction_Write) { + nb_trans_.dbg_trans.write = 1; + nb_trans_.dbg_trans.wdata = trans->wpayload.b64[0]; + } + + ETransStatus ret = TRANS_OK; + nb_trans_.dbg_trans.addr = off64 & 0x7FFF; + nb_trans_.dbg_trans.region = (off64 >> 15) & 0x3; + if (nb_trans_.dbg_trans.region == 3) { + ret = b_transport(trans); + cb->nb_response(trans); + } else { + icpu_->nb_transport_debug_port(&nb_trans_.dbg_trans, this); + } + return ret; +} + +void DSU::nb_response_debug_port(DebugPortTransactionType *trans) { + nb_trans_.p_axi_trans->response = MemResp_Valid; + nb_trans_.p_axi_trans->rpayload.b64[0] = trans->rdata; + nb_trans_.iaxi_cb->nb_response(nb_trans_.p_axi_trans); +} + +void DSU::readLocal(uint64_t off, Axi4TransactionType *trans) { + switch (off >> 3) { + case 0: + trans->rpayload.b64[0] = soft_reset_; + break; + case 8: + trans->rpayload.b64[0] = info_[0].w_cnt; + break; + case 9: + trans->rpayload.b64[0] = info_[0].r_cnt; + break; + case 12: + trans->rpayload.b64[0] = info_[2].w_cnt; + break; + case 13: + trans->rpayload.b64[0] = info_[2].r_cnt; + break; + default: + trans->rpayload.b64[0] = 0; + } + if (trans->xsize == 4 && (off & 0x4) == 0x4) { + trans->rpayload.b64[0] >>= 32; + } +} + +void DSU::writeLocal(uint64_t off, Axi4TransactionType *trans) { + if (trans->xsize == 4) { + if ((off & 0x4) == 0) { + wdata64_ = trans->wpayload.b32[0]; + return; + } else { + wdata64_ |= static_cast(trans->wpayload.b32[0]) << 32; + } + } else { + wdata64_ = trans->wpayload.b64[0]; + } + switch (off >> 3) { + case 0: // soft reset + if (wdata64_ & 0x1) { + icpurst_->reset(true); + } else { + icpurst_->reset(false); + } + soft_reset_ = wdata64_; + break; + default:; + } +} + +void DSU::incrementRdAccess(int mst_id) { + info_[mst_id].r_cnt++; +} + +void DSU::incrementWrAccess(int mst_id) { + info_[mst_id].w_cnt++; +} + +} // namespace debugger +
debug/dsu.cpp Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: debug/dsu.h =================================================================== --- debug/dsu.h (nonexistent) +++ debug/dsu.h (revision 5) @@ -0,0 +1,79 @@ +/** + * @file + * @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved. + * @author Sergey Khabarov - sergeykhbr@gmail.com + * @brief Debug Support Unit (DSU) functional model. + * + * @details DSU supports both types of transaction: blocking and + * non-blocking it allows to interact with SystemC in the + * same manner as with the Functional model. + * @note CPU Functional model must implement non-blocking interface + */ + +#ifndef __DEBUGGER_COMMON_DEBUG_DSU_H__ +#define __DEBUGGER_COMMON_DEBUG_DSU_H__ + +#include +#include +#include "coreservices/imemop.h" +#include "coreservices/ireset.h" +#include "coreservices/icpugen.h" +#include "coreservices/idsugen.h" + +namespace debugger { + +class DSU : public IService, + public IMemoryOperation, + public IDbgNbResponse, + public IDsuGeneric { + public: + explicit DSU(const char *name); + ~DSU(); + + /** IService interface */ + virtual void postinitService(); + + /** IMemoryOperation */ + virtual ETransStatus b_transport(Axi4TransactionType *trans); + virtual ETransStatus nb_transport(Axi4TransactionType *trans, + IAxi4NbResponse *cb); + + /** IDbgNbResponse */ + virtual void nb_response_debug_port(DebugPortTransactionType *trans); + + /** IDsuGeneric */ + virtual void incrementRdAccess(int mst_id); + virtual void incrementWrAccess(int mst_id); + + private: + void readLocal(uint64_t off, Axi4TransactionType *trans); + void writeLocal(uint64_t off, Axi4TransactionType *trans); + + private: + AttributeType cpu_; + AttributeType bus_; + ICpuGeneric *icpu_; + IResetListener *icpurst_; + IMemoryOperation *ibus_; + uint64_t shifter32_; + uint64_t wdata64_; + uint64_t soft_reset_; + + struct nb_trans_type { + Axi4TransactionType *p_axi_trans; + IAxi4NbResponse *iaxi_cb; + DebugPortTransactionType dbg_trans; + } nb_trans_; + + static const int BUS_MASTERS_MAX = 64; + struct BusUtilType { + uint64_t w_cnt; + uint64_t r_cnt; + } info_[BUS_MASTERS_MAX]; +}; + +DECLARE_CLASS(DSU) + +} // namespace debugger + +#endif // __DEBUGGER_COMMON_DEBUG_DSU_H__
debug/dsu.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property Index: debug/greth.cpp =================================================================== --- debug/greth.cpp (nonexistent) +++ debug/greth.cpp (revision 5) @@ -0,0 +1,168 @@ +/** + * @file + * @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved. + * @author Sergey Khabarov - sergeykhbr@gmail.com + * @brief Ethernet MAC device functional model. + */ + +#include +#include "greth.h" +#include "coreservices/isocinfo.h" + +namespace debugger { + +/** Class registration in the Core */ +REGISTER_CLASS(Greth) + +Greth::Greth(const char *name) + : IService(name) { + registerInterface(static_cast(this)); + registerInterface(static_cast(this)); + registerInterface(static_cast(this)); + registerAttribute("IP", &ip_); + registerAttribute("MAC", &mac_); + registerAttribute("Bus", &bus_); + registerAttribute("Transport", &transport_); + registerAttribute("SysBusMasterID", &sysBusMasterID_); + + memset(txbuf_, 0, sizeof(txbuf_)); + seq_cnt_ = 35; + RISCV_event_create(&event_tap_, "UART_event_tap"); +} +Greth::~Greth() { + RISCV_event_close(&event_tap_); +} + +void Greth::postinitService() { + ibus_ = static_cast( + RISCV_get_service_iface(bus_.to_string(), IFACE_MEMORY_OPERATION)); + + if (!ibus_) { + RISCV_error("Bus interface '%s' not found", + bus_.to_string()); + return; + } + + itransport_ = static_cast( + RISCV_get_service_iface(transport_.to_string(), IFACE_LINK)); + + if (!itransport_) { + RISCV_error("UDP interface '%s' not found", + bus_.to_string()); + return; + } + + AttributeType clks; + RISCV_get_clock_services(&clks); + if (clks.size()) { + iclk0_ = static_cast(clks[0u].to_iface()); + } else { + RISCV_error("CPUs not found", NULL); + } + + // Get global settings: + const AttributeType *glb = RISCV_get_global_settings(); + if ((*glb)["SimEnable"].to_bool()) { + if (!run()) { + RISCV_error("Can't create thread.", NULL); + return; + } + } +} + +void Greth::busyLoop() { + int bytes; + uint8_t *tbuf; + uint32_t bytes_to_read; + UdpEdclCommonType req; + RISCV_info("Ethernet thread was started", NULL); + trans_.source_idx = sysBusMasterID_.to_int(); + + while (isEnabled()) { + bytes = + itransport_->readData(rxbuf_, static_cast(sizeof(rxbuf_))); + + if (bytes == 0) { + continue; + } + + req.control.word = read32(&rxbuf_[2]); + req.address = read32(&rxbuf_[6]); + if (seq_cnt_ != req.control.request.seqidx) { + sendNAK(&req); + continue; + } + + trans_.addr = req.address; + if (req.control.request.write == 0) { + trans_.action = MemAction_Read; + trans_.wstrb = 0; + tbuf = &txbuf_[10]; + bytes = sizeof(UdpEdclCommonType) + req.control.request.len; + } else { + trans_.action = MemAction_Write; + tbuf = &rxbuf_[10]; + bytes = sizeof(UdpEdclCommonType); + } + bytes_to_read = req.control.request.len; + while (bytes_to_read) { + trans_.xsize = bytes_to_read; + if (trans_.xsize > 8) { + trans_.xsize = 8; + } + if (trans_.action == MemAction_Write) { + memcpy(trans_.wpayload.b8, tbuf, trans_.xsize); + trans_.wstrb = (1 << trans_.xsize) - 1; + } + RISCV_event_clear(&event_tap_); + ibus_->nb_transport(&trans_, this); + if (RISCV_event_wait_ms(&event_tap_, 500) != 0) { + RISCV_error("CPU queue callback timeout", NULL); + } else if (trans_.action == MemAction_Read) { + memcpy(tbuf, trans_.rpayload.b8, trans_.xsize); + } + tbuf += trans_.xsize; + trans_.addr += trans_.xsize; + bytes_to_read -= trans_.xsize; + } + + req.control.response.nak = 0; + req.control.response.seqidx = seq_cnt_; + write32(&txbuf_[2], req.control.word); + + seq_cnt_++; + itransport_->sendData(txbuf_, bytes); + } +} + +void Greth::nb_response(Axi4TransactionType *trans) { + RISCV_event_set(&event_tap_); +} + +ETransStatus Greth::b_transport(Axi4TransactionType *trans) { + RISCV_error("ETH Slave registers not implemented", NULL); + return TRANS_OK; +} + +void Greth::sendNAK(UdpEdclCommonType *req) { + req->control.response.nak = 1; + req->control.response.seqidx = seq_cnt_; + req->control.response.len = 0; + write32(&txbuf_[2], req->control.word); + write32(&txbuf_[6], req->address); + + itransport_->sendData(txbuf_, sizeof(UdpEdclCommonType)); +} + +uint32_t Greth::read32(uint8_t *buf) { + return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3] << 0); +} + +void Greth::write32(uint8_t *buf, uint32_t v) { + buf[0] = static_cast((v >> 24) & 0xFF); + buf[1] = static_cast((v >> 16) & 0xFF); + buf[2] = static_cast((v >> 8) & 0xFF); + buf[3] = static_cast(v & 0xFF); +} + +} // namespace debugger
debug/greth.cpp Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: debug/greth.h =================================================================== --- debug/greth.h (nonexistent) +++ debug/greth.h (revision 5) @@ -0,0 +1,109 @@ +/** + * @file + * @copyright Copyright 2016 GNSS Sensor Ltd. All right reserved. + * @author Sergey Khabarov - sergeykhbr@gmail.com + * @brief Ethernet MAC device functional model. + */ + +#ifndef __DEBUGGER_COMMON_DEBUG_GRETH_H__ +#define __DEBUGGER_COMMON_DEBUG_GRETH_H__ + +#include +#include +#include "coreservices/ithread.h" +#include "coreservices/iclock.h" +#include "coreservices/imemop.h" +#include "coreservices/ilink.h" +#include "coreservices/irawlistener.h" + +namespace debugger { + +struct greth_map { + uint32_t rsrv1; + uint64_t rsrv[2]; +}; + +struct EdclControlRequestType { + // 32 bits fields: + uint32_t unused : 7; + uint32_t len : 10; + uint32_t write : 1; // read = 0; write = 1 + uint32_t seqidx : 14; // sequence id + /* uint32 data; */ // 0 to 242 words +}; + + +struct EdclControlResponseType { + // 32 bits fields: + uint32_t unused : 7; + uint32_t len : 10; + uint32_t nak : 1; // ACK = 0; NAK = 1 + uint32_t seqidx : 14; // sequence id + /* uint32 data; */ // 0 to 242 words +}; + +#pragma pack(1) +struct UdpEdclCommonType { + uint16_t offset; + union ControlType { + uint32_t word; + EdclControlRequestType request; + EdclControlResponseType response; + } control; + uint32_t address; + /* uint32 data; */ // 0 to 242 words +}; +#pragma pack() + +class Greth : public IService, + public IThread, + public IMemoryOperation, + public IAxi4NbResponse { + public: + explicit Greth(const char *name); + virtual ~Greth(); + + /** IService interface */ + virtual void postinitService(); + + /** IMemoryOperation */ + virtual ETransStatus b_transport(Axi4TransactionType *trans); + + /** IAxi4NbResponse */ + virtual void nb_response(Axi4TransactionType *trans); + + protected: + /** IThread interface */ + virtual void busyLoop(); + + private: + void write32(uint8_t *buf, uint32_t v); + uint32_t read32(uint8_t *buf); + void sendNAK(UdpEdclCommonType *req); + + private: + AttributeType ip_; + AttributeType mac_; + AttributeType bus_; + AttributeType transport_; + AttributeType sysBusMasterID_; + + IMemoryOperation *ibus_; + IClock *iclk0_; + ILink *itransport_; + + uint8_t rxbuf_[1<<12]; + uint8_t txbuf_[1<<12]; + uint32_t seq_cnt_ : 14; + + Axi4TransactionType trans_; + event_def event_tap_; + + greth_map regs_; +}; + +DECLARE_CLASS(Greth) + +} // namespace debugger + +#endif // __DEBUGGER_COMMON_DEBUG_GRETH_H__
debug/greth.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property Index: generic/cpu_generic.cpp =================================================================== --- generic/cpu_generic.cpp (nonexistent) +++ generic/cpu_generic.cpp (revision 5) @@ -0,0 +1,508 @@ +/* + * Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "cpu_generic.h" +#include "coreservices/isocinfo.h" + +namespace debugger { + +CpuGeneric::CpuGeneric(const char *name) + : IService(name), IHap(HAP_ConfigDone), + pc_(this, "pc", DSUREG(ureg.v.pc)), + npc_(this, "npc", DSUREG(ureg.v.npc)), + status_(this, "status", DSUREG(udbg.v.control)), + stepping_cnt_(this, "stepping_cnt", DSUREG(udbg.v.stepping_mode_steps)), + clock_cnt_(this, "clock_cnt", DSUREG(udbg.v.clock_cnt)), + executed_cnt_(this, "executed_cnt", DSUREG(udbg.v.executed_cnt)), + stackTraceCnt_(this, "stack_trace_cnt", DSUREG(ureg.v.stack_trace_cnt)), + stackTraceBuf_(this, "stack_trace_buf", DSUREG(ureg.v.stack_trace_buf), 0), + br_control_(this, "br_control", DSUREG(udbg.v.br_ctrl)), + br_fetch_addr_(this, "br_fetch_addr", DSUREG(udbg.v.br_address_fetch)), + br_fetch_instr_(this, "br_fetch_instr", DSUREG(udbg.v.br_instr_fetch)), + br_hw_add_(this, "br_hw_add", DSUREG(udbg.v.add_breakpoint)), + br_hw_remove_(this, "br_hw_remove", DSUREG(udbg.v.remove_breakpoint)) { + registerInterface(static_cast(this)); + registerInterface(static_cast(this)); + registerInterface(static_cast(this)); + registerInterface(static_cast(this)); + registerInterface(static_cast(this)); + registerInterface(static_cast(this)); + registerAttribute("Enable", &isEnable_); + registerAttribute("SysBus", &sysBus_); + registerAttribute("DbgBus", &dbgBus_); + registerAttribute("SysBusWidthBytes", &sysBusWidthBytes_); + registerAttribute("SourceCode", &sourceCode_); + registerAttribute("StackTraceSize", &stackTraceSize_); + registerAttribute("FreqHz", &freqHz_); + registerAttribute("GenerateRegTraceFile", &generateRegTraceFile_); + registerAttribute("GenerateMemTraceFile", &generateMemTraceFile_); + registerAttribute("ResetVector", &resetVector_); + registerAttribute("SysBusMasterID", &sysBusMasterID_); + + char tstr[256]; + RISCV_sprintf(tstr, sizeof(tstr), "eventConfigDone_%s", name); + RISCV_event_create(&eventConfigDone_, tstr); + RISCV_register_hap(static_cast(this)); + + isysbus_ = 0; + estate_ = CORE_OFF; + step_cnt_ = 0; + pc_z_.val = 0; + hw_stepping_break_ = 0; + interrupt_pending_ = 0; + sw_breakpoint_ = false; + hw_breakpoint_ = false; + skip_sw_breakpoint_ = false; + hwBreakpoints_.make_list(0); + + dport_.valid = 0; + reg_trace_file = 0; + mem_trace_file = 0; +} + +CpuGeneric::~CpuGeneric() { + RISCV_event_close(&eventConfigDone_); + if (reg_trace_file) { + reg_trace_file->close(); + delete reg_trace_file; + } + if (mem_trace_file) { + mem_trace_file->close(); + delete mem_trace_file; + } +} + +void CpuGeneric::postinitService() { + isysbus_ = static_cast( + RISCV_get_service_iface(sysBus_.to_string(), IFACE_MEMORY_OPERATION)); + if (!isysbus_) { + RISCV_error("System Bus interface '%s' not found", + sysBus_.to_string()); + return; + } + + idbgbus_ = static_cast( + RISCV_get_service_iface(dbgBus_.to_string(), IFACE_MEMORY_OPERATION)); + if (!idbgbus_) { + RISCV_error("Debug Bus interface '%s' not found", + dbgBus_.to_string()); + return; + } + + isrc_ = static_cast( + RISCV_get_service_iface(sourceCode_.to_string(), IFACE_SOURCE_CODE)); + if (!isrc_) { + RISCV_error("Source code interface '%s' not found", + sourceCode_.to_string()); + return; + } + + stackTraceBuf_.setRegTotal(2 * stackTraceSize_.to_int()); + + // Get global settings: + const AttributeType *glb = RISCV_get_global_settings(); + if ((*glb)["SimEnable"].to_bool() && isEnable_.to_bool()) { + if (!run()) { + RISCV_error("Can't create thread.", NULL); + return; + } + if (generateRegTraceFile_.to_bool()) { + reg_trace_file = new std::ofstream("river_func_regs.log"); + } + if (generateMemTraceFile_.to_bool()) { + mem_trace_file = new std::ofstream("river_func_mem.log"); + } + } +} + +void CpuGeneric::hapTriggered(IFace *isrc, EHapType type, + const char *descr) { + RISCV_event_set(&eventConfigDone_); +} + +void CpuGeneric::busyLoop() { + RISCV_event_wait(&eventConfigDone_); + + while (isEnabled()) { + updatePipeline(); + } +} + +void CpuGeneric::updatePipeline() { + if (dport_.valid) { + dport_.valid = 0; + updateDebugPort(); + } + + if (!updateState()) { + return; + } + + pc_.setValue(npc_.getValue()); + branch_ = false; + oplen_ = 0; + + if (!checkHwBreakpoint()) { + fetchILine(); + instr_ = decodeInstruction(cacheline_); + + trackContextStart(); + if (instr_) { + oplen_ = instr_->exec(cacheline_); + } else { + generateIllegalOpcode(); + } + trackContextEnd(); + + pc_z_ = pc_.getValue(); + } + + if (!branch_) { + npc_.setValue(pc_.getValue().val + oplen_); + } + + updateQueue(); + + handleTrap(); +} + +bool CpuGeneric::updateState() { + bool upd = true; + switch (estate_) { + case CORE_OFF: + case CORE_Halted: + updateQueue(); + upd = false; + break; + case CORE_Stepping: + if (hw_stepping_break_ <= step_cnt_) { + halt("Stepping breakpoint"); + upd = false; + } + break; + default:; + } + if (upd) { + step_cnt_++; + } + return upd; +} + +void CpuGeneric::updateQueue() { + IFace *cb; + queue_.initProc(); + queue_.pushPreQueued(); + + while ((cb = queue_.getNext(step_cnt_)) != 0) { + static_cast(cb)->stepCallback(step_cnt_); + } +} + +void CpuGeneric::fetchILine() { + trans_.action = MemAction_Read; + trans_.addr = pc_.getValue().val; + trans_.xsize = 4; + trans_.wstrb = 0; + dma_memop(&trans_); + cacheline_[0].val = trans_.rpayload.b64[0]; + if (skip_sw_breakpoint_ && trans_.addr == br_fetch_addr_.getValue().val) { + skip_sw_breakpoint_ = false; + cacheline_[0].buf32[0] = br_fetch_instr_.getValue().buf32[0]; + } +} + +void CpuGeneric::registerStepCallback(IClockListener *cb, + uint64_t t) { + if (!isEnabled() && t <= step_cnt_) { + cb->stepCallback(t); + return; + } + queue_.put(t, cb); +} + +void CpuGeneric::setBranch(uint64_t npc) { + branch_ = true; + npc_.setValue(npc); +} + +void CpuGeneric::pushStackTrace() { + int cnt = static_cast(stackTraceCnt_.getValue().val); + if (cnt >= stackTraceSize_.to_int()) { + return; + } + stackTraceBuf_.write(2*cnt, pc_.getValue().val); + stackTraceBuf_.write(2*cnt + 1, npc_.getValue().val); + stackTraceCnt_.setValue(cnt + 1); +} + +void CpuGeneric::popStackTrace() { + uint64_t cnt = stackTraceCnt_.getValue().val; + if (cnt) { + stackTraceCnt_.setValue(cnt - 1); + } +} + +void CpuGeneric::dma_memop(Axi4TransactionType *tr) { + tr->source_idx = sysBusMasterID_.to_int(); + if (tr->xsize <= sysBusWidthBytes_.to_uint32()) { + isysbus_->b_transport(tr); + } else { + // 1-byte access for HC08 + Axi4TransactionType tr1 = *tr; + tr1.xsize = 1; + tr1.wstrb = 1; + for (unsigned i = 0; i < tr->xsize; i++) { + tr1.addr = tr->addr + i; + if (tr->action == MemAction_Write) { + tr1.wpayload.b8[0] = tr->wpayload.b8[i]; + } + isysbus_->b_transport(&tr1); + if (tr->action == MemAction_Read) { + tr->rpayload.b8[i] = tr1.rpayload.b8[0]; + } + } + } + if (!mem_trace_file) { + //if (!reg_trace_file) { + return; + } + + char tstr[512]; + Reg64Type pload = {0}; + if (tr->action == MemAction_Read) { + if (tr->xsize == 4) { + pload.buf32[0] = tr->rpayload.b32[0]; + } else { + pload.val = tr->rpayload.b64[0]; + } + RISCV_sprintf(tstr, sizeof(tstr), + "%08x: [%08x] => %016" RV_PRI64 "x\n", + pc_.getValue().buf32[0], + static_cast(tr->addr), + pload.val); + } else { + if (tr->xsize == 4) { + pload.buf32[0] = tr->wpayload.b32[0]; + } else { + pload.val = tr->wpayload.b64[0]; + } + RISCV_sprintf(tstr, sizeof(tstr), + "%08x: [%08x] <= %016" RV_PRI64 "x\n", + pc_.getValue().buf32[0], + static_cast(tr->addr), + pload.val); + } + (*mem_trace_file) << tstr; + mem_trace_file->flush(); +} + +void CpuGeneric::go() { + if (estate_ == CORE_OFF) { + RISCV_error("CPU is turned-off", 0); + return; + } + estate_ = CORE_Normal; +} + +void CpuGeneric::step() { + if (estate_ == CORE_OFF) { + RISCV_error("CPU is turned-off", 0); + return; + } + hw_stepping_break_ = step_cnt_ + stepping_cnt_.getValue().val; + estate_ = CORE_Stepping; +} + +void CpuGeneric::halt(const char *descr) { + if (estate_ == CORE_OFF) { + RISCV_error("CPU is turned-off", 0); + return; + } + char strop[32]; + uint8_t tbyte; + unsigned bytetot = oplen_; + if (!bytetot) { + bytetot = 1; + } + for (unsigned i = 0; i < bytetot; i++) { + if (endianess() == LittleEndian) { + tbyte = cacheline_[0].buf[bytetot-i-1]; + } else { + tbyte = cacheline_[0].buf[i]; + } + RISCV_sprintf(&strop[2*i], sizeof(strop)-2*i, "%02x", tbyte); + } + + if (descr == NULL) { + RISCV_info("[%6" RV_PRI64 "d] pc:%04" RV_PRI64 "x: %s \t CPU halted", + step_cnt_, pc_.getValue().val, strop); + } else { + RISCV_info("[%6" RV_PRI64 "d] pc:%04" RV_PRI64 "x: %s\t %s", + step_cnt_, pc_.getValue().val, strop, descr); + } + estate_ = CORE_Halted; + RISCV_trigger_hap(getInterface(IFACE_SERVICE), HAP_Halt, "Descr"); +} + +void CpuGeneric::reset(bool active) { + interrupt_pending_ = 0; + status_.reset(active); + stackTraceCnt_.reset(active); + pc_.setValue(getResetAddress()); + npc_.setValue(getResetAddress()); + if (!active && estate_ == CORE_OFF) { + // Turn ON: + estate_ = CORE_Halted;//CORE_Normal; + RISCV_trigger_hap(static_cast(this), + HAP_CpuTurnON, "CPU Turned ON"); + } else if (active) { + // Turn OFF: + estate_ = CORE_OFF; + RISCV_trigger_hap(static_cast(this), + HAP_CpuTurnOFF, "CPU Turned OFF"); + } + hw_breakpoint_ = false; + sw_breakpoint_ = false; +} + +void CpuGeneric::updateDebugPort() { + DebugPortTransactionType *trans = dport_.trans; + Axi4TransactionType tr; + tr.xsize = 8; + tr.source_idx = 0; + if (trans->write) { + tr.action = MemAction_Write; + tr.wpayload.b64[0] = trans->wdata; + tr.wstrb = 0xFF; + } else { + tr.action = MemAction_Read; + tr.rpayload.b64[0] = 0; + } + tr.addr = (static_cast(trans->region) << 15) | trans->addr; + idbgbus_->b_transport(&tr); + + trans->rdata = tr.rpayload.b64[0];; + dport_.cb->nb_response_debug_port(trans); +} + +void CpuGeneric::nb_transport_debug_port(DebugPortTransactionType *trans, + IDbgNbResponse *cb) { + dport_.trans = trans; + dport_.cb = cb; + dport_.valid = true; +} + +void CpuGeneric::addHwBreakpoint(uint64_t addr) { + AttributeType item; + item.make_uint64(addr); + hwBreakpoints_.add_to_list(&item); + hwBreakpoints_.sort(); + for (unsigned i = 0; i < hwBreakpoints_.size(); i++) { + RISCV_debug("Breakpoint[%d]: 0x%04" RV_PRI64 "x", + i, hwBreakpoints_[i].to_uint64()); + } +} + +void CpuGeneric::removeHwBreakpoint(uint64_t addr) { + for (unsigned i = 0; i < hwBreakpoints_.size(); i++) { + if (addr == hwBreakpoints_[i].to_uint64()) { + hwBreakpoints_.remove_from_list(i); + hwBreakpoints_.sort(); + return; + } + } +} + +bool CpuGeneric::checkHwBreakpoint() { + uint64_t pc = pc_.getValue().val; + if (hw_breakpoint_ && pc == hw_break_addr_) { + hw_breakpoint_ = false; + return false; + } + hw_breakpoint_ = false; + + for (unsigned i = 0; i < hwBreakpoints_.size(); i++) { + uint64_t bradr = hwBreakpoints_[i].to_uint64(); + if (pc < bradr) { + // Sorted list + break; + } + if (pc == bradr) { + hw_break_addr_ = pc; + hw_breakpoint_ = true; + halt("Hw breakpoint"); + return true; + } + } + return false; +} + +void CpuGeneric::skipBreakpoint() { + skip_sw_breakpoint_ = true; + sw_breakpoint_ = false; +} + + +uint64_t GenericStatusType::aboutToRead(uint64_t cur_val) { + GenericCpuControlType ctrl; + CpuGeneric *pcpu = static_cast(parent_); + ctrl.val = 0; + ctrl.bits.halt = pcpu->isHalt() || !pcpu->isOn() ? 1 : 0; + ctrl.bits.sw_breakpoint = pcpu->isSwBreakpoint() ? 1 : 0; + ctrl.bits.hw_breakpoint = pcpu->isHwBreakpoint() ? 1 : 0; + return ctrl.val; +} + +uint64_t GenericStatusType::aboutToWrite(uint64_t new_val) { + GenericCpuControlType ctrl; + CpuGeneric *pcpu = static_cast(parent_); + ctrl.val = new_val; + if (ctrl.bits.halt) { + pcpu->halt("halted from DSU"); + } else if (ctrl.bits.stepping) { + pcpu->step(); + } else { + pcpu->go(); + } + return new_val; +} + +uint64_t FetchedBreakpointType::aboutToWrite(uint64_t new_val) { + CpuGeneric *pcpu = static_cast(parent_); + pcpu->skipBreakpoint(); + return new_val; +} + +uint64_t AddBreakpointType::aboutToWrite(uint64_t new_val) { + CpuGeneric *pcpu = static_cast(parent_); + pcpu->addHwBreakpoint(new_val); + return new_val; +} + +uint64_t RemoveBreakpointType::aboutToWrite(uint64_t new_val) { + CpuGeneric *pcpu = static_cast(parent_); + pcpu->removeHwBreakpoint(new_val); + return new_val; +} + +uint64_t StepCounterType::aboutToRead(uint64_t cur_val) { + CpuGeneric *pcpu = static_cast(parent_); + return pcpu->getStepCounter(); +} + +} // namespace debugger +
generic/cpu_generic.cpp Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: generic/cpu_generic.h =================================================================== --- generic/cpu_generic.h (nonexistent) +++ generic/cpu_generic.h (revision 5) @@ -0,0 +1,226 @@ +/* + * Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DEBUGGER_COMMON_CPU_GENERIC_H__ +#define __DEBUGGER_COMMON_CPU_GENERIC_H__ + +#include +#include +#include +#include +#include "coreservices/ithread.h" +#include "coreservices/icpugen.h" +#include "coreservices/icpufunctional.h" +#include "coreservices/imemop.h" +#include "coreservices/iclock.h" +#include "coreservices/iclklistener.h" +#include "coreservices/ireset.h" +#include "coreservices/isrccode.h" +#include "generic/mapreg.h" +#include "debug/debugmap.h" +#include + +namespace debugger { + +class GenericStatusType : public MappedReg64Type { + public: + GenericStatusType(IService *parent, const char *name, uint64_t addr) : + MappedReg64Type(parent, name, addr) { + } + protected: + virtual uint64_t aboutToRead(uint64_t cur_val); + virtual uint64_t aboutToWrite(uint64_t new_val); +}; + +class FetchedBreakpointType : public MappedReg64Type { + public: + FetchedBreakpointType(IService *parent, const char *name, uint64_t addr) + : MappedReg64Type(parent, name, addr) { + } + protected: + virtual uint64_t aboutToWrite(uint64_t new_val); +}; + +class AddBreakpointType : public MappedReg64Type { + public: + AddBreakpointType(IService *parent, const char *name, uint64_t addr) + : MappedReg64Type(parent, name, addr) { + } + protected: + virtual uint64_t aboutToWrite(uint64_t new_val); +}; + +class RemoveBreakpointType : public MappedReg64Type { + public: + RemoveBreakpointType(IService *parent, const char *name, uint64_t addr) + : MappedReg64Type(parent, name, addr) { + } + protected: + virtual uint64_t aboutToWrite(uint64_t new_val); +}; + +class StepCounterType : public MappedReg64Type { + public: + StepCounterType(IService *parent, const char *name, uint64_t addr) + : MappedReg64Type(parent, name, addr) { + } + protected: + virtual uint64_t aboutToRead(uint64_t cur_val); +}; + +class CpuGeneric : public IService, + public IThread, + public ICpuGeneric, + public ICpuFunctional, + public IClock, + public IResetListener, + public IHap { + public: + explicit CpuGeneric(const char *name); + ~CpuGeneric(); + + /** IService interface */ + virtual void postinitService(); + + /** ICpuGeneric interface */ + virtual void raiseSignal(int idx) = 0; + virtual void lowerSignal(int idx) = 0; + virtual void nb_transport_debug_port(DebugPortTransactionType *trans, + IDbgNbResponse *cb); + + /** ICpuFunctional */ + virtual uint64_t getPC() { return pc_.getValue().val; } + virtual void setBranch(uint64_t npc); + virtual void pushStackTrace(); + virtual void popStackTrace(); + virtual uint64_t getPrvLevel() { return cur_prv_level; } + virtual void setPrvLevel(uint64_t lvl) { cur_prv_level = lvl; } + virtual void dma_memop(Axi4TransactionType *tr); + virtual bool isOn() { return estate_ != CORE_OFF; } + virtual bool isHalt() { return estate_ == CORE_Halted; } + virtual bool isSwBreakpoint() { return sw_breakpoint_; } + virtual bool isHwBreakpoint() { return hw_breakpoint_; } + virtual void go(); + virtual void halt(const char *descr); + virtual void step(); + virtual void addHwBreakpoint(uint64_t addr); + virtual void removeHwBreakpoint(uint64_t addr); + virtual void skipBreakpoint(); + protected: + virtual uint64_t getResetAddress() { return resetVector_.to_uint64(); } + virtual EEndianessType endianess() = 0; + virtual GenericInstruction *decodeInstruction(Reg64Type *cache) = 0; + virtual void generateIllegalOpcode() = 0; + virtual void handleTrap() = 0; + virtual void trackContextStart() {} + virtual void trackContextEnd() {} + + public: + /** IClock */ + virtual uint64_t getStepCounter() { return step_cnt_; } + virtual void registerStepCallback(IClockListener *cb, uint64_t t); + virtual double getFreqHz() { + return static_cast(freqHz_.to_int64()); + } + + /** IResetListener interface */ + virtual void reset(bool active); + + /** IHap */ + virtual void hapTriggered(IFace *isrc, EHapType type, const char *descr); + + protected: + /** IThread interface */ + virtual void busyLoop(); + + void updatePipeline(); + bool updateState(); + void fetchILine(); + void updateDebugPort(); + void updateQueue(); + bool checkHwBreakpoint(); + + protected: + AttributeType isEnable_; + AttributeType freqHz_; + AttributeType sysBus_; + AttributeType dbgBus_; + AttributeType sysBusWidthBytes_; + AttributeType sourceCode_; + AttributeType stackTraceSize_; + AttributeType generateRegTraceFile_; + AttributeType generateMemTraceFile_; + AttributeType resetVector_; + AttributeType sysBusMasterID_; + AttributeType hwBreakpoints_; + + ISourceCode *isrc_; + IMemoryOperation *isysbus_; + IMemoryOperation *idbgbus_; + GenericInstruction *instr_; + + uint64_t step_cnt_; + uint64_t hw_stepping_break_; + bool branch_; + unsigned oplen_; + MappedReg64Type pc_; + MappedReg64Type npc_; + GenericStatusType status_; + MappedReg64Type stepping_cnt_; + StepCounterType clock_cnt_; + StepCounterType executed_cnt_; + MappedReg64Type stackTraceCnt_; // Hardware stack trace buffer + GenericReg64Bank stackTraceBuf_; // [[from,to],*] + MappedReg64Type br_control_; // Enable/disable Trap on break + MappedReg64Type br_fetch_addr_; // Skip breakpoint at address + FetchedBreakpointType br_fetch_instr_; // Use this instruction on address + AddBreakpointType br_hw_add_; + RemoveBreakpointType br_hw_remove_; + + Reg64Type pc_z_; + uint64_t interrupt_pending_; + bool sw_breakpoint_; + bool skip_sw_breakpoint_; + bool hw_breakpoint_; + uint64_t hw_break_addr_; // Last hit breakpoint to skip it on next step + + event_def eventConfigDone_; + ClockAsyncTQueueType queue_; + + enum ECoreState { + CORE_OFF, + CORE_Halted, + CORE_Normal, + CORE_Stepping + } estate_; + + Axi4TransactionType trans_; + Reg64Type cacheline_[512/4]; + struct DebugPortType { + bool valid; + DebugPortTransactionType *trans; + IDbgNbResponse *cb; + } dport_; + + uint64_t cur_prv_level; + + std::ofstream *reg_trace_file; + std::ofstream *mem_trace_file; +}; + +} // namespace debugger + +#endif // __DEBUGGER_COMMON_CPU_GENERIC_H__
generic/cpu_generic.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property Index: generic/iotypes.cpp =================================================================== --- generic/iotypes.cpp (nonexistent) +++ generic/iotypes.cpp (revision 5) @@ -0,0 +1,233 @@ +/* + * Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "iotypes.h" + +namespace debugger { + +IOReg8Type::IOReg8Type(IService *parent, const char *name, + uint16_t addr, uint16_t len, int priority) { + if (parent == NULL) { + } else { + parent->registerPortInterface(name, + static_cast(this)); + parent->registerPortInterface(name, static_cast(this)); + parent->registerPortInterface(name, + static_cast(this)); + } + parent_ = parent; + portListeners_.make_list(0); + regname_.make_string(name); + baseAddress_.make_uint64(addr); + length_.make_uint64(len); + priority_.make_int64(priority); + value.byte = 0; + hard_reset_value_ = 0; +} + +IFace *IOReg8Type::getInterface(const char *name) { + if (strcmp(name, IFACE_MEMORY_OPERATION) == 0) { + return static_cast(this); + } + return parent_->getInterface(name); +} + +void IOReg8Type::reset(bool active) { + if (!active) { + return; + } + write(hard_reset_value_); +} + +ETransStatus IOReg8Type::b_transport(Axi4TransactionType *trans) { + uint16_t addr = static_cast(trans->addr); + if (trans->action == MemAction_Read) { + trans->rpayload.b8[0] = read(); + RISCV_debug("Read %s [%02x] => %02x", + regName(), addr, trans->rpayload.b8[0]); + } else { + write(trans->wpayload.b8[0]); + RISCV_debug("Write %s [%02x] <= %02x", + regName(), addr, trans->wpayload.b8[0]); + } + return TRANS_OK; +} + +uint8_t IOReg8Type::read() { + IIOPortListener *lstn; + uint8_t odata = value.byte; + for (unsigned i = 0; i < portListeners_.size(); i++) { + lstn = static_cast(portListeners_[i].to_iface()); + lstn->readData(&odata, get_direction()); + } + return odata; +} + +void IOReg8Type::write(uint8_t data) { + IIOPortListener *lstn; + value.byte = data; + for (unsigned i = 0; i < portListeners_.size(); i++) { + lstn = static_cast(portListeners_[i].to_iface()); + lstn->writeData(data, get_direction()); + } + for (unsigned i = 0; i < portListeners_.size(); i++) { + lstn = static_cast(portListeners_[i].to_iface()); + lstn->latch(); + } +} + +void IOReg8Type::registerPortListener(IFace *listener) { + AttributeType item; + item.make_iface(listener); + portListeners_.add_to_list(&item); +} + +void IOReg8Type::unregisterPortListener(IFace *listener) { + for (unsigned i = 0; i < portListeners_.size(); i++) { + if (listener == portListeners_[i].to_iface()) { + portListeners_.remove_from_list(i); + break; + } + } +} + +/** */ +IOPinType::IOPinType(IService *parent, const char *name) : parent_(parent) { + pinName_.make_string(name); + iwire_ = 0; + value_ = 0; + bitIdx_ = 0; + access_ = 0; + + char tstr[256]; + RISCV_sprintf(tstr, sizeof(tstr), "pin_%s", name); + parent_->registerAttribute(tstr, &IOPinTypeCfg_); +} + +// Memory access use direction xDD register value (IN/OUT) +void IOPinType::readData(uint8_t *val, uint8_t mask) { + uint8_t v; + if (iwire_ && (access_ & READ_MASK)) { + v = iwire_->getLevel(); + } else { + v = aboutToRead(value_); + } + *val &= ~(1 << bitIdx_); + *val |= (v << bitIdx_); +} + +void IOPinType::writeData(uint8_t val, uint8_t mask) { + prelatch_ = (val >> bitIdx_) & 0x1; + if (iwire_ && (access_ & WRITE_MASK) && (mask & (1u << bitIdx_))) { + iwire_->setLevel(prelatch_ == 0 ? false : true); + } else { + aboutToWrite(value_, prelatch_); + } +} + +// Direct access to wire doesn't use Direction xDD mask register +uint8_t IOPinType::get_bit() { + if (iwire_ && (access_ & READ_MASK)) { + return iwire_->getLevel() ? 1u : 0; + } + return value_; +} + +void IOPinType::set_bit(uint8_t v) { + if (iwire_ && (access_ & WRITE_MASK)) { + iwire_->setLevel(v == 0 ? false : true); + } + prelatch_ = v; + value_ = prelatch_; +} + + +void IOPinType::latch() { + value_ = prelatch_; +} + +void IOPinType::postinit() { + connectToBit(IOPinTypeCfg_); + if (IOPinTypeCfg_.size() >= 3) { + connectToWire(IOPinTypeCfg_[2]); + } +} + +void IOPinType::connectToBit(const AttributeType &cfg) { + if (!cfg.is_list() || cfg.size() < 2) { + RISCV_printf(NULL, LOG_ERROR, + "Cannot connect IOPinType %s: Wrong format of port attribute", + pinName_.to_string()); + return; + } + IIOPort *iport = 0; + if (cfg[0u].is_string()) { + iport = static_cast(RISCV_get_service_iface( + cfg[0u].to_string(), IFACE_IOPORT)); + } else if (cfg[0u].is_list()) { + const AttributeType &prt = cfg[0u]; + iport = static_cast(RISCV_get_service_port_iface( + prt[0u].to_string(), prt[1].to_string(), IFACE_IOPORT)); + } + bitIdx_ = cfg[1].to_int(); + + if (iport == 0) { + RISCV_printf(NULL, LOG_ERROR, + "Cannot connect IOPinType: Can't get port interface %s", + cfg[0u].to_string()); + return; + } + iport->registerPortListener(static_cast(this)); +} + +void IOPinType::connectToWire(const AttributeType &cfg) { + if (!cfg.is_list() || cfg.size() < 2) { + RISCV_printf(NULL, LOG_ERROR, + "[%s] Cannot connect IWire input: wrong attribute", + pinName_.to_string()); + return; + } + const char *rw; + if (cfg.size() == 2) { + iwire_ = static_cast(RISCV_get_service_iface( + cfg[0u].to_string(), IFACE_WIRE)); + rw = cfg[1].to_string(); + } else { + iwire_ = static_cast(RISCV_get_service_port_iface( + cfg[0u].to_string(), cfg[1].to_string(), IFACE_WIRE)); + rw = cfg[2].to_string(); + } + if (!iwire_) { + RISCV_printf(NULL, LOG_ERROR, + "[%s] Cannot find IWire interface in %s", + pinName_.to_string(), cfg[0u].to_string()); + return; + } + + access_ = 0; + if (strstr(rw, "r")) { + access_ |= READ_MASK; + prelatch_ = iwire_->getLevel(); + value_ = prelatch_; + } + if (strstr(rw, "w")) { + access_ |= WRITE_MASK; + } +} + +} // namespace debugger +
generic/iotypes.cpp Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: generic/iotypes.h =================================================================== --- generic/iotypes.h (nonexistent) +++ generic/iotypes.h (revision 5) @@ -0,0 +1,115 @@ +/* + * Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DEBUGGER_COMMON_GENERIC_IOTYPES_H__ +#define __DEBUGGER_COMMON_GENERIC_IOTYPES_H__ + +#include +#include +#include "coreservices/iioport.h" +#include "coreservices/ireset.h" +#include "coreservices/iwire.h" + +namespace debugger { + +class IOReg8Type : public IMemoryOperation, + public IIOPort, + public IResetListener { + public: + IOReg8Type(IService *parent, const char *name, + uint16_t addr, uint16_t len, int priority = 1); + + /** IMemoryOperation methods */ + virtual ETransStatus b_transport(Axi4TransactionType *trans); + + /** IIOPort */ + virtual void registerPortListener(IFace *listener); + virtual void unregisterPortListener(IFace *listener); + + /** IResetListener interface */ + virtual void reset(bool active); + + /** General access methods: */ + const char *regName() { return regname_.to_string(); } + uint8_t getValue() { return value.byte; } + void setValue(uint8_t v) { value.byte = v; } + + protected: + virtual uint8_t read(); + virtual void write(uint8_t val); + virtual uint8_t get_direction() {return 0u; } + + protected: + // Debug output compatibility + IFace *getInterface(const char *name); + + protected: + IService *parent_; + AttributeType regname_; + AttributeType portListeners_; + Reg8Type value; + uint8_t hard_reset_value_; +}; + + +class IOPinType : public IIOPortListener { + public: + IOPinType(IService *parent, const char *name); + + /** IIOPortListener */ + virtual void readData(uint8_t *val, uint8_t mask); + virtual void writeData(uint8_t val, uint8_t mask); + virtual void latch(); + + /** generic accessors */ + void postinit(); + void connectToBit(const AttributeType &cfg); + void connectToWire(const AttributeType &cfg); + uint8_t get_bit(); + void set_bit(uint8_t v); + + protected: + virtual uint8_t aboutToRead(uint8_t val) { return val; } + virtual void aboutToWrite(uint8_t prev, uint8_t val) {} + + protected: + static const int READ_MASK = 0x1; + static const int WRITE_MASK = 0x2; + + AttributeType pinName_; + AttributeType IOPinTypeCfg_; + IService *parent_; + IWire *iwire_; + uint8_t value_; // triggered + uint8_t prelatch_; // not triggered value + int bitIdx_; + int access_; +}; + +class IOPinTypeDebug : public IOPinType { + public: + IOPinTypeDebug(IService *parent, const char *name) + : IOPinType(parent, name) {} + protected: + // Debug output compatibility + IFace *getInterface(const char *name) { + return parent_->getInterface(name); + } +}; + +} // namespace debugger + +#endif // __DEBUGGER_COMMON_GENERIC_IOTYPES_H__
generic/iotypes.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property Index: generic/mapreg.cpp =================================================================== --- generic/mapreg.cpp (nonexistent) +++ generic/mapreg.cpp (revision 5) @@ -0,0 +1,101 @@ +/* + * Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "mapreg.h" + +namespace debugger { + +MappedReg64Type::MappedReg64Type(IService *parent, const char *name, + uint64_t addr, int len, int priority) { + if (parent == NULL) { + } else { + parent->registerPortInterface(name, + static_cast(this)); + parent->registerPortInterface(name, + static_cast(this)); + } + parent_ = parent; + portListeners_.make_list(0); + regname_.make_string(name); + baseAddress_.make_uint64(addr); + length_.make_uint64(len); + priority_.make_int64(priority); + value_.val = 0; + hard_reset_value_ = 0; +} + +IFace *MappedReg64Type::getInterface(const char *name) { + if (strcmp(name, IFACE_MEMORY_OPERATION) == 0) { + return static_cast(this); + } + return parent_->getInterface(name); +} + +void MappedReg64Type::reset(bool active) { + if (!active) { + return; + } + value_.val = hard_reset_value_; +} + +ETransStatus MappedReg64Type::b_transport(Axi4TransactionType *trans) { + uint64_t off = trans->addr - getBaseAddress(); + if (trans->action == MemAction_Read) { + Reg64Type cur; + cur.val = aboutToRead(value_.val); + memcpy(trans->rpayload.b8, &cur.buf[off], trans->xsize); + RISCV_debug("Read %s [%02" RV_PRI64 "x] => %016" RV_PRI64 "x", + regName(), trans->addr, trans->rpayload.b64[0]); + } else { + Reg64Type new_val = value_; + memcpy(&new_val.buf[off], trans->wpayload.b8, trans->xsize); + new_val.val = aboutToWrite(new_val.val); + value_ = new_val; + RISCV_debug("Write %s [%02" RV_PRI64 "x] <= %016" RV_PRI64 "x", + regName(), trans->addr, trans->wpayload.b64[0]); + } + return TRANS_OK; +} + +ETransStatus GenericReg64Bank::b_transport(Axi4TransactionType *trans) { + int idx = static_cast((trans->addr - getBaseAddress()) >> 3); + if (trans->action == MemAction_Read) { + trans->rpayload.b64[0] = read(idx).val; + } else { + write(idx, trans->wpayload.b64[0]); + } + return TRANS_OK; +} + +void GenericReg64Bank::reset() { + memset(regs_, 0, length_.to_int()); +} + +void GenericReg64Bank::setRegTotal(int len) { + if (len * static_cast(sizeof(Reg64Type)) == length_.to_int()) { + return; + } + if (regs_) { + delete [] regs_; + } + length_.make_int64(len * sizeof(Reg64Type)); + regs_ = new Reg64Type[len]; + reset(); +} + +} // namespace debugger +
generic/mapreg.cpp Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: generic/mapreg.h =================================================================== --- generic/mapreg.h (nonexistent) +++ generic/mapreg.h (revision 5) @@ -0,0 +1,104 @@ +/* + * Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DEBUGGER_COMMON_GENERIC_MAPREG_H__ +#define __DEBUGGER_COMMON_GENERIC_MAPREG_H__ + +#include +#include +#include "coreservices/imemop.h" +#include "coreservices/ireset.h" + +namespace debugger { + +class MappedReg64Type : public IMemoryOperation, + public IResetListener { + public: + MappedReg64Type(IService *parent, const char *name, + uint64_t addr, int len = 8, int priority = 1); + + /** IMemoryOperation methods */ + virtual ETransStatus b_transport(Axi4TransactionType *trans); + + /** IResetListener interface */ + virtual void reset(bool active); + + /** General access methods: */ + const char *regName() { return regname_.to_string(); } + Reg64Type getValue() { return value_; } + void setValue(Reg64Type v) { value_ = v; } + void setValue(uint64_t v) { value_.val = v; } + + protected: + /** Possible side effects handlers: */ + virtual uint64_t aboutToRead(uint64_t cur_val) { + return cur_val; + } + virtual uint64_t aboutToWrite(uint64_t new_val) { + return new_val; + } + protected: + // Debug output compatibility + IFace *getInterface(const char *name); + + protected: + IService *parent_; + AttributeType regname_; + AttributeType portListeners_; + Reg64Type value_; + uint64_t hard_reset_value_; +}; + + +class GenericReg64Bank : public IMemoryOperation { + public: + GenericReg64Bank(IService *parent, const char *name, + uint64_t addr, int len) { + parent->registerPortInterface(name, + static_cast(this)); + regs_ = 0; + bankName_.make_string(name); + baseAddress_.make_uint64(addr); + setRegTotal(len); + } + virtual ~GenericReg64Bank() { + if (regs_) { + delete [] regs_; + } + } + + /** IMemoryOperation methods */ + virtual ETransStatus b_transport(Axi4TransactionType *trans); + + /** IResetListener interface */ + virtual void reset(); + + /** General access methods: */ + void setRegTotal(int len); + Reg64Type read(int idx) { return regs_[idx]; } + void write(int idx, Reg64Type val) { regs_[idx] = val; } + void write(int idx, uint64_t val) { regs_[idx].val = val; } + Reg64Type *getp() { return regs_; } + uint64_t *getpR64() { return ®s_[0].val; } + + protected: + AttributeType bankName_; + Reg64Type *regs_; +}; + +} // namespace debugger + +#endif // __DEBUGGER_COMMON_GENERIC_MAPREG_H__
generic/mapreg.h Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Rev URL \ No newline at end of property

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.