1848SN/A/*
21762SN/A * Copyright (c) 2004-2005 The Regents of The University of Michigan
3848SN/A * All rights reserved.
4848SN/A *
5848SN/A * Redistribution and use in source and binary forms, with or without
6848SN/A * modification, are permitted provided that the following conditions are
7848SN/A * met: redistributions of source code must retain the above copyright
8848SN/A * notice, this list of conditions and the following disclaimer;
9848SN/A * redistributions in binary form must reproduce the above copyright
10848SN/A * notice, this list of conditions and the following disclaimer in the
11848SN/A * documentation and/or other materials provided with the distribution;
12848SN/A * neither the name of the copyright holders nor the names of its
13848SN/A * contributors may be used to endorse or promote products derived from
14848SN/A * this software without specific prior written permission.
15848SN/A *
16848SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17848SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18848SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19848SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20848SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21848SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22848SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23848SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24848SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25848SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26848SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665SN/A *
282665SN/A * Authors: Andrew Schultz
292665SN/A *          Miguel Serrano
30848SN/A */
31848SN/A
32848SN/A/** @file
33864SN/A * Simple PCI IDE controller with bus mastering capability and UDMA
34864SN/A * modeled after controller in the Intel PIIX4 chip
35848SN/A */
36848SN/A
3711264Sandreas.sandberg@arm.com#ifndef __DEV_STORAGE_IDE_CTRL_HH__
3811264Sandreas.sandberg@arm.com#define __DEV_STORAGE_IDE_CTRL_HH__
39848SN/A
405772SN/A#include "base/bitunion.hh"
418229SN/A#include "dev/io_device.hh"
4211260SN/A#include "dev/pci/device.hh"
434762SN/A#include "params/IdeController.hh"
44848SN/A
45849SN/Aclass IdeDisk;
46848SN/A
47848SN/A/**
48848SN/A * Device model for an Intel PIIX4 IDE controller
49848SN/A */
50848SN/A
519807SN/Aclass IdeController : public PciDevice
52848SN/A{
535772SN/A  private:
545772SN/A    // Bus master IDE status register bit fields
555772SN/A    BitUnion8(BMIStatusReg)
565772SN/A        Bitfield<6> dmaCap0;
575772SN/A        Bitfield<5> dmaCap1;
585772SN/A        Bitfield<2> intStatus;
595772SN/A        Bitfield<1> dmaError;
605772SN/A        Bitfield<0> active;
615772SN/A    EndBitUnion(BMIStatusReg)
621149SN/A
635772SN/A    BitUnion8(BMICommandReg)
645772SN/A        Bitfield<3> rw;
655772SN/A        Bitfield<0> startStop;
665772SN/A    EndBitUnion(BMICommandReg)
671817SN/A
685772SN/A    struct Channel
695772SN/A    {
705772SN/A        std::string _name;
715772SN/A
725772SN/A        const std::string
735772SN/A        name()
745772SN/A        {
755772SN/A            return _name;
765772SN/A        }
775772SN/A
785772SN/A        /** Command and control block registers */
795772SN/A        Addr cmdAddr, cmdSize, ctrlAddr, ctrlSize;
805772SN/A
815772SN/A        /** Registers used for bus master interface */
825772SN/A        struct BMIRegs
835772SN/A        {
8412895Sjason@lowepower.com            void reset() {
8512895Sjason@lowepower.com                memset(static_cast<void *>(this), 0, sizeof(*this));
8612895Sjason@lowepower.com            }
8712895Sjason@lowepower.com
885772SN/A            BMICommandReg command;
895772SN/A            uint8_t reserved0;
905772SN/A            BMIStatusReg status;
915772SN/A            uint8_t reserved1;
925772SN/A            uint32_t bmidtp;
935772SN/A        } bmiRegs;
945772SN/A
955772SN/A        /** IDE disks connected to this controller */
965772SN/A        IdeDisk *master, *slave;
975772SN/A
985772SN/A        /** Currently selected disk */
995772SN/A        IdeDisk *selected;
1005772SN/A
1015772SN/A        bool selectBit;
1025772SN/A
1035772SN/A        void
1045772SN/A        select(bool selSlave)
1055772SN/A        {
1065772SN/A            selectBit = selSlave;
1075772SN/A            selected = selectBit ? slave : master;
1085772SN/A        }
1095772SN/A
1105772SN/A        void accessCommand(Addr offset, int size, uint8_t *data, bool read);
1115772SN/A        void accessControl(Addr offset, int size, uint8_t *data, bool read);
1125772SN/A        void accessBMI(Addr offset, int size, uint8_t *data, bool read);
1135772SN/A
1145772SN/A        Channel(std::string newName, Addr _cmdSize, Addr _ctrlSize);
1155772SN/A        ~Channel();
1165772SN/A
11710905SN/A        void serialize(const std::string &base, std::ostream &os) const;
11810905SN/A        void unserialize(const std::string &base, CheckpointIn &cp);
1195776SN/A    };
1205772SN/A
1215776SN/A    Channel primary;
1225776SN/A    Channel secondary;
1235772SN/A
124848SN/A    /** Bus master interface (BMI) registers */
1255772SN/A    Addr bmiAddr, bmiSize;
126848SN/A
1271817SN/A    /** Registers used in device specific PCI configuration */
1285772SN/A    uint16_t primaryTiming, secondaryTiming;
1295772SN/A    uint8_t deviceTiming;
1305772SN/A    uint8_t udmaControl;
1315772SN/A    uint16_t udmaTiming;
1325772SN/A    uint16_t ideConfig;
133848SN/A
134848SN/A    // Internal management variables
1355772SN/A    bool ioEnabled;
1365772SN/A    bool bmEnabled;
137848SN/A
1387750SN/A    uint32_t ioShift, ctrlOffset;
1397750SN/A
1405772SN/A    void dispatchAccess(PacketPtr pkt, bool read);
141929SN/A
142929SN/A  public:
1434762SN/A    typedef IdeControllerParams Params;
1441149SN/A    const Params *params() const { return (const Params *)_params; }
1451149SN/A    IdeController(Params *p);
146848SN/A
1475772SN/A    /** See if a disk is selected based on its pointer */
1485772SN/A    bool isDiskSelected(IdeDisk *diskPtr);
1495772SN/A
1505772SN/A    void intrPost();
1515772SN/A
15211169SN/A    Tick writeConfig(PacketPtr pkt) override;
15311169SN/A    Tick readConfig(PacketPtr pkt) override;
154848SN/A
155849SN/A    void setDmaComplete(IdeDisk *disk);
156849SN/A
15711169SN/A    Tick read(PacketPtr pkt) override;
15811169SN/A    Tick write(PacketPtr pkt) override;
159848SN/A
16011168SN/A    void serialize(CheckpointOut &cp) const override;
16111168SN/A    void unserialize(CheckpointIn &cp) override;
162848SN/A};
16311264Sandreas.sandberg@arm.com#endif // __DEV_STORAGE_IDE_CTRL_HH_
164