15794SN/A/*
25794SN/A * Copyright (c) 2008 The Regents of The University of Michigan
35794SN/A * All rights reserved.
45794SN/A *
55794SN/A * Redistribution and use in source and binary forms, with or without
65794SN/A * modification, are permitted provided that the following conditions are
75794SN/A * met: redistributions of source code must retain the above copyright
85794SN/A * notice, this list of conditions and the following disclaimer;
95794SN/A * redistributions in binary form must reproduce the above copyright
105794SN/A * notice, this list of conditions and the following disclaimer in the
115794SN/A * documentation and/or other materials provided with the distribution;
125794SN/A * neither the name of the copyright holders nor the names of its
135794SN/A * contributors may be used to endorse or promote products derived from
145794SN/A * this software without specific prior written permission.
155794SN/A *
165794SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175794SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185794SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195794SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205794SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215794SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225794SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235794SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245794SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255794SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265794SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275794SN/A *
285794SN/A * Authors: Ali Saidi
295794SN/A */
305794SN/A
315794SN/A/* @file
325794SN/A * Register and structure descriptions for Intel's I/O AT DMA Engine
335794SN/A */
345794SN/A#include "base/bitfield.hh"
355794SN/A#include "sim/serialize.hh"
365794SN/A
375794SN/Anamespace CopyEngineReg {
385794SN/A
395794SN/A
405794SN/A// General Channel independant registers, 128 bytes starting at 0x00
415794SN/Aconst uint32_t GEN_CHANCOUNT    = 0x00;
425794SN/Aconst uint32_t GEN_XFERCAP      = 0x01;
435794SN/Aconst uint32_t GEN_INTRCTRL     = 0x03;
445794SN/Aconst uint32_t GEN_ATTNSTATUS   = 0x04;
455794SN/A
465794SN/A
475794SN/A// Channel specific registers, each block is 128 bytes, starting at 0x80
485794SN/Aconst uint32_t CHAN_CONTROL         = 0x00;
495794SN/Aconst uint32_t CHAN_STATUS          = 0x04;
505794SN/Aconst uint32_t CHAN_CHAINADDR       = 0x0C;
515794SN/Aconst uint32_t CHAN_CHAINADDR_LOW   = 0x0C;
525794SN/Aconst uint32_t CHAN_CHAINADDR_HIGH  = 0x10;
535794SN/Aconst uint32_t CHAN_COMMAND         = 0x14;
545794SN/Aconst uint32_t CHAN_CMPLNADDR       = 0x18;
555794SN/Aconst uint32_t CHAN_CMPLNADDR_LOW   = 0x18;
565794SN/Aconst uint32_t CHAN_CMPLNADDR_HIGH  = 0x1C;
575794SN/Aconst uint32_t CHAN_ERROR           = 0x28;
585794SN/A
595794SN/A
605794SN/Aconst uint32_t DESC_CTRL_INT_GEN    = 0x00000001;
615794SN/Aconst uint32_t DESC_CTRL_SRC_SN     = 0x00000002;
625794SN/Aconst uint32_t DESC_CTRL_DST_SN     = 0x00000004;
635794SN/Aconst uint32_t DESC_CTRL_CP_STS     = 0x00000008;
645794SN/Aconst uint32_t DESC_CTRL_FRAME      = 0x00000010;
655794SN/Aconst uint32_t DESC_CTRL_NULL       = 0x00000020;
665794SN/A
675794SN/Astruct DmaDesc {
685794SN/A    uint32_t len;
695794SN/A    uint32_t command;
705794SN/A    Addr src;
715794SN/A    Addr dest;
725794SN/A    Addr next;
735794SN/A    uint64_t reserved1;
745794SN/A    uint64_t reserved2;
755794SN/A    uint64_t user1;
765794SN/A    uint64_t user2;
775794SN/A};
785794SN/A
795794SN/A#define ADD_FIELD8(NAME, OFFSET, BITS) \
805794SN/A    inline uint8_t NAME() { return bits(_data, OFFSET+BITS-1, OFFSET); } \
815794SN/A    inline void NAME(uint8_t d) { replaceBits(_data, OFFSET+BITS-1, OFFSET,d); }
825794SN/A
835794SN/A#define ADD_FIELD16(NAME, OFFSET, BITS) \
845794SN/A    inline uint16_t NAME() { return bits(_data, OFFSET+BITS-1, OFFSET); } \
855794SN/A    inline void NAME(uint16_t d) { replaceBits(_data, OFFSET+BITS-1, OFFSET,d); }
865794SN/A
875794SN/A#define ADD_FIELD32(NAME, OFFSET, BITS) \
885794SN/A    inline uint32_t NAME() { return bits(_data, OFFSET+BITS-1, OFFSET); } \
895794SN/A    inline void NAME(uint32_t d) { replaceBits(_data, OFFSET+BITS-1, OFFSET,d); }
905794SN/A
915794SN/A#define ADD_FIELD64(NAME, OFFSET, BITS) \
925794SN/A    inline uint64_t NAME() { return bits(_data, OFFSET+BITS-1, OFFSET); } \
935794SN/A    inline void NAME(uint64_t d) { replaceBits(_data, OFFSET+BITS-1, OFFSET,d); }
945794SN/A
955794SN/Atemplate<class T>
965794SN/Astruct Reg {
975794SN/A    T _data;
985794SN/A    T operator()() { return _data; }
995794SN/A    const Reg<T> &operator=(T d) { _data = d; return *this;}
1005794SN/A    bool operator==(T d) { return d == _data; }
1015794SN/A    void operator()(T d) { _data = d; }
1025794SN/A    Reg() { _data = 0; }
10310905SN/A    void serialize(CheckpointOut &cp) const
1045794SN/A    {
1055794SN/A        SERIALIZE_SCALAR(_data);
1065794SN/A    }
10710905SN/A    void unserialize(CheckpointIn &cp)
1085794SN/A    {
1095794SN/A        UNSERIALIZE_SCALAR(_data);
1105794SN/A    }
1115794SN/A};
1125794SN/A
1135794SN/A
11410905SN/Astruct Regs : public Serializable {
1155794SN/A    uint8_t chanCount;
1165794SN/A    uint8_t xferCap;
1175794SN/A
1185794SN/A    struct INTRCTRL : public Reg<uint8_t> { // 0x03
1195794SN/A        using Reg<uint8_t>::operator =;
1205794SN/A        ADD_FIELD8(master_int_enable,0,1);
1215794SN/A        ADD_FIELD8(interrupt_status,1,1);
1225794SN/A        ADD_FIELD8(interrupt,2,1);
1235794SN/A    };
1245794SN/A    INTRCTRL intrctrl;
1255794SN/A
1265794SN/A    uint32_t attnStatus; // Read clears
1275794SN/A
12811168SN/A    void serialize(CheckpointOut &cp) const override
1295794SN/A    {
1305794SN/A        SERIALIZE_SCALAR(chanCount);
1315794SN/A        SERIALIZE_SCALAR(xferCap);
13210905SN/A        paramOut(cp, "intrctrl", intrctrl._data);
1335794SN/A        SERIALIZE_SCALAR(attnStatus);
1345794SN/A    }
1355794SN/A
13611168SN/A    void unserialize(CheckpointIn &cp) override
1375794SN/A    {
1385794SN/A        UNSERIALIZE_SCALAR(chanCount);
1395794SN/A        UNSERIALIZE_SCALAR(xferCap);
14010905SN/A        paramIn(cp, "intrctrl", intrctrl._data);
1415794SN/A        UNSERIALIZE_SCALAR(attnStatus);
1425794SN/A    }
1435794SN/A
1445794SN/A};
1455794SN/A
14610905SN/Astruct ChanRegs : public Serializable {
1475794SN/A    struct CHANCTRL : public Reg<uint16_t> { // channelX + 0x00
1485794SN/A        using Reg<uint16_t>::operator =;
1495794SN/A        ADD_FIELD16(interrupt_disable,0,1);
1505794SN/A        ADD_FIELD16(error_completion_enable, 2,1);
1515794SN/A        ADD_FIELD16(any_error_abort_enable,3,1);
1525794SN/A        ADD_FIELD16(error_int_enable,4,1);
1535794SN/A        ADD_FIELD16(desc_addr_snoop_control,5,1);
1545794SN/A        ADD_FIELD16(in_use, 8,1);
1555794SN/A    };
1565794SN/A    CHANCTRL ctrl;
1575794SN/A
1585794SN/A    struct CHANSTS : public Reg<uint64_t> { // channelX + 0x04
1595794SN/A        ADD_FIELD64(dma_transfer_status, 0, 3);
1605794SN/A        ADD_FIELD64(unaffiliated_error, 3, 1);
1615794SN/A        ADD_FIELD64(soft_error, 4, 1);
1625794SN/A        ADD_FIELD64(compl_desc_addr, 6, 58);
1635794SN/A    };
1645794SN/A    CHANSTS status;
1655794SN/A
1665794SN/A    uint64_t descChainAddr;
1675794SN/A
1685794SN/A    struct CHANCMD : public Reg<uint8_t> { // channelX + 0x14
1695794SN/A        ADD_FIELD8(start_dma,0,1);
1705794SN/A        ADD_FIELD8(append_dma,1,1);
1715794SN/A        ADD_FIELD8(suspend_dma,2,1);
1725794SN/A        ADD_FIELD8(abort_dma,3,1);
1735794SN/A        ADD_FIELD8(resume_dma,4,1);
1745794SN/A        ADD_FIELD8(reset_dma,5,1);
1755794SN/A    };
1765794SN/A    CHANCMD command;
1775794SN/A
1785794SN/A    uint64_t completionAddr;
1795794SN/A
1805794SN/A    struct CHANERR : public Reg<uint32_t> { // channel X + 0x28
1815794SN/A        ADD_FIELD32(source_addr_error,0,1);
1825794SN/A        ADD_FIELD32(dest_addr_error,1,1);
1835794SN/A        ADD_FIELD32(ndesc_addr_error,2,1);
1845794SN/A        ADD_FIELD32(desc_error,3,1);
1855794SN/A        ADD_FIELD32(chain_addr_error,4,1);
1865794SN/A        ADD_FIELD32(chain_cmd_error,5,1);
1875794SN/A        ADD_FIELD32(chipset_parity_error,6,1);
1885794SN/A        ADD_FIELD32(dma_parity_error,7,1);
1895794SN/A        ADD_FIELD32(read_data_error,8,1);
1905794SN/A        ADD_FIELD32(write_data_error,9,1);
1915794SN/A        ADD_FIELD32(desc_control_error,10,1);
1925794SN/A        ADD_FIELD32(desc_len_error,11,1);
1935794SN/A        ADD_FIELD32(completion_addr_error,12,1);
1945794SN/A        ADD_FIELD32(interrupt_config_error,13,1);
1955794SN/A        ADD_FIELD32(soft_error,14,1);
1965794SN/A        ADD_FIELD32(unaffiliated_error,15,1);
1975794SN/A    };
1985794SN/A    CHANERR error;
1995794SN/A
20011168SN/A    void serialize(CheckpointOut &cp) const override
2015794SN/A    {
20210905SN/A        paramOut(cp, "ctrl", ctrl._data);
20310905SN/A        paramOut(cp, "status", status._data);
2045794SN/A        SERIALIZE_SCALAR(descChainAddr);
20510905SN/A        paramOut(cp, "command", command._data);
2065794SN/A        SERIALIZE_SCALAR(completionAddr);
20710905SN/A        paramOut(cp, "error", error._data);
2085794SN/A    }
2095794SN/A
21011168SN/A    void unserialize(CheckpointIn &cp) override
2115794SN/A    {
21210905SN/A        paramIn(cp, "ctrl", ctrl._data);
21310905SN/A        paramIn(cp, "status", status._data);
2145794SN/A        UNSERIALIZE_SCALAR(descChainAddr);
21510905SN/A        paramIn(cp, "command", command._data);
2165794SN/A        UNSERIALIZE_SCALAR(completionAddr);
21710905SN/A        paramIn(cp, "error", error._data);
2185794SN/A    }
2195794SN/A
2205794SN/A
2215794SN/A};
2225794SN/A
2237811SN/A} // namespace CopyEngineReg
2245794SN/A
2255794SN/A
226