ide_ctrl.hh revision 1817
1/* 2 * Copyright (c) 2004-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29/** @file 30 * Simple PCI IDE controller with bus mastering capability and UDMA 31 * modeled after controller in the Intel PIIX4 chip 32 */ 33 34#ifndef __IDE_CTRL_HH__ 35#define __IDE_CTRL_HH__ 36 37#include "dev/pcidev.hh" 38#include "dev/pcireg.h" 39#include "dev/io_device.hh" 40 41#define BMIC0 0x0 // Bus master IDE command register 42#define BMIS0 0x2 // Bus master IDE status register 43#define BMIDTP0 0x4 // Bus master IDE descriptor table pointer register 44#define BMIC1 0x8 // Bus master IDE command register 45#define BMIS1 0xa // Bus master IDE status register 46#define BMIDTP1 0xc // Bus master IDE descriptor table pointer register 47 48// Bus master IDE command register bit fields 49#define RWCON 0x08 // Bus master read/write control 50#define SSBM 0x01 // Start/stop bus master 51 52// Bus master IDE status register bit fields 53#define DMA1CAP 0x40 // Drive 1 DMA capable 54#define DMA0CAP 0x20 // Drive 0 DMA capable 55#define IDEINTS 0x04 // IDE Interrupt Status 56#define IDEDMAE 0x02 // IDE DMA error 57#define BMIDEA 0x01 // Bus master IDE active 58 59// IDE Command byte fields 60#define IDE_SELECT_OFFSET (6) 61#define IDE_SELECT_DEV_BIT 0x10 62 63#define IDE_FEATURE_OFFSET IDE_ERROR_OFFSET 64#define IDE_COMMAND_OFFSET IDE_STATUS_OFFSET 65 66// IDE Timing Register bit fields 67#define IDETIM_DECODE_EN 0x8000 68 69// PCI device specific register byte offsets 70#define IDE_CTRL_CONF_START 0x40 71#define IDE_CTRL_CONF_END ((IDE_CTRL_CONF_START) + sizeof(config_regs)) 72 73 74enum IdeRegType { 75 COMMAND_BLOCK, 76 CONTROL_BLOCK, 77 BMI_BLOCK 78}; 79 80class BaseInterface; 81class Bus; 82class HierParams; 83class IdeDisk; 84class IntrControl; 85class PciConfigAll; 86class PhysicalMemory; 87class Platform; 88 89/** 90 * Device model for an Intel PIIX4 IDE controller 91 */ 92 93class IdeController : public PciDev 94{ 95 friend class IdeDisk; 96 97 enum IdeChannel { 98 PRIMARY = 0, 99 SECONDARY = 1 100 }; 101 102 private: 103 /** Primary command block registers */ 104 Addr pri_cmd_addr; 105 Addr pri_cmd_size; 106 /** Primary control block registers */ 107 Addr pri_ctrl_addr; 108 Addr pri_ctrl_size; 109 /** Secondary command block registers */ 110 Addr sec_cmd_addr; 111 Addr sec_cmd_size; 112 /** Secondary control block registers */ 113 Addr sec_ctrl_addr; 114 Addr sec_ctrl_size; 115 /** Bus master interface (BMI) registers */ 116 Addr bmi_addr; 117 Addr bmi_size; 118 119 private: 120 /** Registers used for bus master interface */ 121 union { 122 uint8_t data[16]; 123 124 struct { 125 uint8_t bmic0; 126 uint8_t reserved_0; 127 uint8_t bmis0; 128 uint8_t reserved_1; 129 uint32_t bmidtp0; 130 uint8_t bmic1; 131 uint8_t reserved_2; 132 uint8_t bmis1; 133 uint8_t reserved_3; 134 uint32_t bmidtp1; 135 }; 136 137 struct { 138 uint8_t bmic; 139 uint8_t reserved_4; 140 uint8_t bmis; 141 uint8_t reserved_5; 142 uint32_t bmidtp; 143 } chan[2]; 144 145 } bmi_regs; 146 /** Shadows of the device select bit */ 147 uint8_t dev[2]; 148 /** Registers used in device specific PCI configuration */ 149 union { 150 uint8_t data[22]; 151 152 struct { 153 uint16_t idetim0; 154 uint16_t idetim1; 155 uint8_t sidetim; 156 uint8_t reserved_0[3]; 157 uint8_t udmactl; 158 uint8_t reserved_1; 159 uint16_t udmatim; 160 uint8_t reserved_2[8]; 161 uint16_t ideconfig; 162 }; 163 } config_regs; 164 165 // Internal management variables 166 bool io_enabled; 167 bool bm_enabled; 168 bool cmd_in_progress[4]; 169 170 private: 171 /** IDE disks connected to controller */ 172 IdeDisk *disks[4]; 173 174 private: 175 /** Parse the access address to pass on to device */ 176 void parseAddr(const Addr &addr, Addr &offset, IdeChannel &channel, 177 IdeRegType ®_type); 178 179 /** Select the disk based on the channel and device bit */ 180 int getDisk(IdeChannel channel); 181 182 /** Select the disk based on a pointer */ 183 int getDisk(IdeDisk *diskPtr); 184 185 public: 186 /** See if a disk is selected based on its pointer */ 187 bool isDiskSelected(IdeDisk *diskPtr); 188 189 public: 190 struct Params : public PciDev::Params 191 { 192 /** Array of disk objects */ 193 std::vector<IdeDisk *> disks; 194 Bus *host_bus; 195 Tick pio_latency; 196 HierParams *hier; 197 }; 198 const Params *params() const { return (const Params *)_params; } 199 200 public: 201 IdeController(Params *p); 202 ~IdeController(); 203 204 virtual void writeConfig(int offset, int size, const uint8_t *data); 205 virtual void readConfig(int offset, int size, uint8_t *data); 206 207 void setDmaComplete(IdeDisk *disk); 208 209 /** 210 * Read a done field for a given target. 211 * @param req Contains the address of the field to read. 212 * @param data Return the field read. 213 * @return The fault condition of the access. 214 */ 215 virtual Fault read(MemReqPtr &req, uint8_t *data); 216 217 /** 218 * Write to the mmapped I/O control registers. 219 * @param req Contains the address to write to. 220 * @param data The data to write. 221 * @return The fault condition of the access. 222 */ 223 virtual Fault write(MemReqPtr &req, const uint8_t *data); 224 225 /** 226 * Serialize this object to the given output stream. 227 * @param os The stream to serialize to. 228 */ 229 virtual void serialize(std::ostream &os); 230 231 /** 232 * Reconstruct the state of this object from a checkpoint. 233 * @param cp The checkpoint use. 234 * @param section The section name of this object 235 */ 236 virtual void unserialize(Checkpoint *cp, const std::string §ion); 237 238 /** 239 * Return how long this access will take. 240 * @param req the memory request to calcuate 241 * @return Tick when the request is done 242 */ 243 Tick cacheAccess(MemReqPtr &req); 244}; 245#endif // __IDE_CTRL_HH_ 246