|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.0 (the 'License'). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License."
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24: /*
25: * Copyright 1997-1998 by Apple Computer, Inc., All rights reserved.
26: * Copyright 1994-1997 NeXT Software, Inc., All rights reserved.
27: *
28: * IdePIIX.m - PIIX/PCI specific ATA controller initialization module.
29: *
30: * 23-Jan-1998 Joe Liu at Apple
31: * Added support for PIIX/PIIX3/PIIX4 PCI IDE controllers.
32: *
33: * 05-Apr-1995 Rakesh Dubey at NeXT
34: * Fixed some bugs in PCI support.
35: * 03-Oct-1994 Rakesh Dubey at NeXT
36: * Created.
37: */
38:
39: #import "IdeCnt.h"
40: #import "IdePIIX.h"
41: #import "IdeCntCmds.h"
42: #import <driverkit/i386/IOPCIDeviceDescription.h>
43: #import <driverkit/i386/IOPCIDirectDevice.h>
44: #import <driverkit/generalFuncs.h>
45: #import <driverkit/kernelDriver.h>
46: #import <driverkit/interruptMsg.h>
47: #import <mach/mach_interface.h>
48: #import <machdep/i386/io_inline.h>
49: #import <string.h>
50: #import <stdio.h>
51: #import "IdeDDM.h"
52: #import "PIIX.h"
53: #import "PIIXTiming.h"
54: #import "IdeShared.h"
55:
56: // XXX get rid of this
57: #if (IO_DRIVERKIT_VERSION != 330)
58: #import <machdep/machine/pmap.h>
59: #endif
60:
61: extern vm_offset_t pmap_resident_extract(pmap_t pmap, vm_offset_t va);
62:
63: //#define DEBUG
64:
65: #ifndef MIN
66: #define MIN(a,b) ((a) < (b) ? (a) : (b))
67: #endif MIN
68:
69: #ifndef MAX
70: #define MAX(a,b) ((a) > (b) ? (a) : (b))
71: #endif MAX
72:
73: /*
74: * Function: IOMallocPage
75: *
76: * Purpose:
77: * Returns a pointer to a page-aligned memory block of size >= PAGE_SIZE.
78: * Note that on Intel, the hardware page size of 4K. However, MACH's
79: * notion of a page is 8K, which is comprised of two contiguous
80: * (physical/virtual) hardware pages.
81: *
82: * Return:
83: * Actual pointer and size of block returned in actual_ptr and actual_size.
84: * Use these as arguments to IOFree: IOFree(*actual_ptr, *actual_size);
85: */
86: static void *
87: IOMallocPage(int request_size, void ** actual_ptr,
88: int * actual_size)
89: {
90: void * mem_ptr;
91:
92: /*
93: * Minimize memory use by first trying to allocate the requested size
94: * without any padding.
95: */
96: *actual_size = round_page(request_size);
97: mem_ptr = IOMalloc(*actual_size);
98: if (mem_ptr == NULL)
99: return NULL;
100:
101: /*
102: * Check alignment of this page.
103: */
104: if ((vm_offset_t)mem_ptr & (PAGE_SIZE - 1)) { // NOT page aligned.
105: IOFree(mem_ptr, *actual_size);
106: *actual_size = round_page(request_size) + PAGE_SIZE;
107: mem_ptr = IOMalloc(*actual_size);
108: if (mem_ptr == NULL)
109: return NULL;
110: }
111:
112: *actual_ptr = mem_ptr;
113: return ((void *)round_page(mem_ptr));
114: }
115:
116: @implementation IdeController(PIIX)
117:
118: /*
119: * Method: probePCIController
120: *
121: * Purpose:
122: * Probe the existence of a supported PCI chipset, then proceed to
123: * record the PCI IDE controller found.
124: *
125: * Note:
126: * This is called before [super init...], and so we use the class version
127: * of getPCIdevice method calls.
128: *
129: */
130: - (BOOL) probePCIController:(IOPCIDeviceDescription *)devDesc
131: {
132: unsigned char devNum, funcNum, busNum;
133: const char *value;
134: const char *deviceName;
135: IOConfigTable *configTable;
136: IOReturn rtn;
137: const id self_class = [self class];
138:
139: /*
140: * Initialize PCI ivars.
141: */
142: _controllerID = PCI_ID_NONE;
143: _ideChannel = PCI_CHANNEL_OTHER;
144: _busMaster = NO;
145: bzero((char *)&_prdTable, sizeof(_prdTable));
146:
147: /*
148: * Make sure we are dealing with a PCI config table by reading the
149: * BUS_TYPE key.
150: */
151: configTable = [devDesc configTable];
152: value = [configTable valueForStringKey:BUS_TYPE];
153: if (!value || strcmp(value, "PCI") != 0) {
154: // Not PCI, return YES to continue probing for non PCI controllers.
155: return YES;
156: }
157:
158: /*
159: * Read PCI config space for VendorID and DeviceID.
160: */
161: rtn = [devDesc getPCIdevice:&devNum function:&funcNum bus:&busNum];
162: if (rtn != IO_R_SUCCESS) {
163: IOLog("%s: Unsupported PCI hardware\n", [self name]);
164: return NO;
165: }
166: rtn = [self_class getPCIConfigData:&_controllerID atRegister:0x00
167: withDeviceDescription:devDesc];
168: if (rtn != IO_R_SUCCESS) {
169: IOLog("%s: PCI config space access error %d\n", [self name], rtn);
170: return NO;
171: }
172:
173: switch (_controllerID) {
174: case PCI_ID_PIIX:
175: deviceName = "PIIX";
176: break;
177: case PCI_ID_PIIX3:
178: deviceName = "PIIX3";
179: break;
180: case PCI_ID_PIIX4:
181: deviceName = "PIIX4";
182: break;
183: default:
184: IOLog("%s: Unknown PCI IDE controller (0x%08lx)\n",
185: [self name], _controllerID);
186: _controllerID = PCI_ID_NONE;
187: return NO;
188: }
189:
190: /*
191: * Report the PCI controller found.
192: */
193: IOLog("%s: %s PCI IDE Controller at Dev:%d Func:%d Bus:%d\n",
194: [self name], deviceName, devNum, funcNum, busNum);
195:
196: /*
197: * At this point, we are certain that we are dealing with a
198: * Intel PIIX class controller.
199: */
200: return ([self PIIXInitController:devDesc]);
201: }
202:
203: /*
204: * Method: initPIIXController
205: *
206: * Initializes the Intel PIIX IDE controller.
207: */
208: - (BOOL) PIIXInitController:(IOPCIDeviceDescription *)devDesc
209: {
210: piix_idetim_u idetim;
211: IOReturn rtn;
212: unsigned long configReg;
213: const id self_class = [self class];
214:
215: /*
216: * Are we initializing the primary or the secondary channel?
217: * Set the ivar _ideChannel.
218: */
219: switch ([devDesc portRangeList]->start) {
220: case PIIX_P_CMD_ADDR:
221: _ideChannel = PCI_CHANNEL_PRIMARY;
222: break;
223: case PIIX_S_CMD_ADDR:
224: _ideChannel = PCI_CHANNEL_SECONDARY;
225: break;
226: default:
227: _ideChannel = PCI_CHANNEL_OTHER;
228: }
229:
230: /*
231: * PIIX configured on a weird location, cannot continue.
232: *
233: * NOTE:
234: * The I/O ranges does NOT show up as a I/O range in the PCI
235: * configuration space. However, the Bus-Mastering I/O range
236: * does show up at configuration space location 0x20.
237: */
238: if ((_ideChannel == PCI_CHANNEL_OTHER) ||
239: ([devDesc portRangeList]->size != PIIX_CMD_SIZE)) {
240: IOLog("%s: Invalid IDE Command Block set to 0x%x size %d\n",
241: [self name],
242: [devDesc portRangeList]->start,
243: [devDesc portRangeList]->size);
244: return NO;
245: }
246:
247: /*
248: * Verify our IRQ assignment.
249: *
250: * PIIX hardcodes the following settings:
251: * IRQ 14 - primary channel
252: * IRQ 15 - secondary channel
253: */
254: {
255: unsigned int irq;
256:
257: irq = (_ideChannel == PCI_CHANNEL_PRIMARY) ? PIIX_P_IRQ : PIIX_S_IRQ;
258: if ([devDesc interrupt] != irq) {
259: IOLog("%s: Invalid IRQ: %d\n", [self name], [devDesc interrupt]);
260: return NO;
261: }
262: }
263:
264: /*
265: * Check the I/O Space Enable bit in the PCI command register.
266: *
267: * This is the master enable bit for the PIIX controller.
268: */
269: rtn = [self_class getPCIConfigData:&configReg atRegister:PIIX_PCICMD
270: withDeviceDescription:devDesc];
271: if (rtn != IO_R_SUCCESS) {
272: IOLog("%s: PCI config space access error %d\n", [self name], rtn);
273: return NO;
274: }
275: if (!(configReg & 0x0001)) {
276: IOLog("%s: PCI IDE controller is not enabled\n", [self name]);
277: return NO;
278: }
279: if (configReg & 0x0004)
280: _busMaster = YES;
281: else
282: _busMaster = NO;
283:
284: /*
285: * Fetch the corresponding primary/secondary IDETIM register and
286: * verify that the individual channels are enabled.
287: */
288: rtn = [self_class getPCIConfigData:&configReg atRegister:PIIX_IDETIM
289: withDeviceDescription:devDesc];
290: if (rtn != IO_R_SUCCESS) {
291: IOLog("%s: PCI config space access error %d\n", [self name], rtn);
292: return NO;
293: }
294: if (_ideChannel == PCI_CHANNEL_SECONDARY)
295: configReg >>= 16; // PIIX_IDETIM + 2 for secondary channel
296: idetim.word = (u_short)configReg;
297:
298: if (!idetim.bits.ide) {
299: IOLog("%s: %s PCI IDE channel is not enabled\n",
300: [self name],
301: (_ideChannel == PCI_CHANNEL_PRIMARY) ? "Primary" : "Secondary");
302: return NO;
303: }
304:
305: /*
306: * Register and record the location of our Bus Master
307: * interface registers.
308: */
309: if (_busMaster && ([self PIIXRegisterBMRange:devDesc] == NO)) {
310: IOLog("%s: Bus master I/O range registration failed\n",
311: [self name]);
312: _busMaster = NO;
313: }
314:
315: /*
316: * Allocate a 4K-page (perhaps 8K) aligned page of memory for
317: * the PRD table.
318: */
319: if (_busMaster && ([self PIIXInitPRDTable] == NO)) {
320: IOLog("%s: cannot allocate memory for descriptor table\n",
321: [self name]);
322: _busMaster = NO;
323: }
324:
325: #if 0
326: IOLog("%s: PCI bus master DMA: %s\n",
327: [self name], busMaster ? "Enabled" : "Disabled");
328: #endif
329:
330: /*
331: * Revert to default timing.
332: */
333: [self PIIXResetTimings:devDesc];
334:
335: return YES;
336: }
337:
338: /*
339: * Method: getPCIControllerCapabilities
340: *
341: * Return the capability of the PCI IDE controller in 'm'.
342: *
343: */
344: - (void) getPCIControllerCapabilities:(txferModes_t *)m
345: {
346: m->mode.swdma = m->mode.mwdma = m->mode.udma = ATA_MODE_NONE;
347: switch (_controllerID) {
348: case PCI_ID_PIIX:
349: case PCI_ID_PIIX3:
350: case PCI_ID_PIIX4:
351: m->mode.pio = ata_mode_to_mask(ATA_MODE_4);
352: if (_busMaster) {
353: m->mode.mwdma = ata_mode_to_mask(ATA_MODE_2);
354: if (_controllerID == PCI_ID_PIIX4)
355: m->mode.udma = ata_mode_to_mask(ATA_MODE_2);
356: }
357: break;
358: }
359: }
360:
361: /*
362: * Get the PIO port transfer width. This refers to the width of the
363: * I/O transfer on the PIO port, the IDE bus width is always 16-bits.
364: *
365: * All PIIX controllers are capable of 32-bit transfers on the data
366: * port.
367: */
368: - (ideTransferWidth_t) getPIOTransferWidth
369: {
370: return (IDE_TRANSFER_32_BIT);
371: }
372:
373: /*
374: * Method: resetPCIController
375: *
376: * Not a true RESET, simply return the PCI controller to a quiescent state
377: * and return all IDE ports to the default timing.
378: */
379: - (void) resetPCIController
380: {
381: switch (_controllerID) {
382: case PCI_ID_PIIX:
383: case PCI_ID_PIIX3:
384: case PCI_ID_PIIX4:
385: [self PIIXInit];
386: [self PIIXResetTimings:[self deviceDescription]];
387: break;
388: }
389: }
390:
391: /*
392: * Method: PIIXResetTimings
393: *
394: * Purpose:
395: * Revert the timing register to the default value. The transfer timing
396: * is set to the compatible mode. We need to be careful to initialize the
397: * register only for our current IDE channel.
398: */
399: - (void) PIIXResetTimings:(IOPCIDeviceDescription *)devDesc
400: {
401: union {
402: u_long dword;
403: struct {
404: piix_idetim_u pri;
405: piix_idetim_u sec;
406: } tim;
407: } timings;
408:
409: IOReturn rtn;
410: u_long udma;
411:
412: /*
413: * Read the PIIX_IDETIM register.
414: */
415: rtn = [[self class] getPCIConfigData:&timings.dword
416: atRegister:PIIX_IDETIM
417: withDeviceDescription:devDesc];
418: if (rtn != IO_R_SUCCESS)
419: return;
420:
421: /*
422: * Read both PIIX_UDMACTL and PIIX_UDMATIM register.
423: */
424: rtn = [[self class] getPCIConfigData:&udma atRegister:PIIX_UDMACTL
425: withDeviceDescription:devDesc];
426:
427: /*
428: * Set compatible timing.
429: * Disable UDDMA and set its timing registers to the slowest mode.
430: */
431: switch (_ideChannel) {
432: case PCI_CHANNEL_PRIMARY:
433: timings.tim.pri.word &= 0x8000;
434: udma &= 0xffccfffc;
435: break;
436: case PCI_CHANNEL_SECONDARY:
437: timings.tim.sec.word &= 0x8000;
438: udma &= 0xccfffff3;
439: break;
440: default:
441: return;
442: }
443:
444: /*
445: * Write the modified PCI config space registers back.
446: */
447: [[self class] setPCIConfigData:timings.dword atRegister:PIIX_IDETIM
448: withDeviceDescription:devDesc];
449: [[self class] setPCIConfigData:udma atRegister:PIIX_UDMACTL
450: withDeviceDescription:devDesc];
451: }
452:
453: /*
454: * Method: PIIXRegisterBMRange:
455: *
456: * Purpose:
457: * Add the 8-byte Bus-Master control registers to the portRangeList in
458: * the deviceDescription. The base address for the registers resides in
459: * PCI config space location 0x20. The first 8 bytes are for the primary
460: * IDE channel, the next eight bytes are for the secondary IDE channel.
461: *
462: * Note:
463: * This must be called before [super init...] because that's when the
464: * resources are registered.
465: */
466: - (BOOL) PIIXRegisterBMRange:(IOPCIDeviceDescription *)devDesc
467: {
468: IOReturn rtn;
469: unsigned long bmiba;
470: IORange io_range[2];
471:
472: rtn = [[self class] getPCIConfigData:&bmiba atRegister:PIIX_BMIBA
473: withDeviceDescription:devDesc];
474: if (rtn != IO_R_SUCCESS) {
475: IOLog("%s: PCI config space access error %d\n", [self name], rtn);
476: return NO;
477: }
478:
479: /*
480: * Sanity check. Make sure this is an I/O range.
481: */
482: if ((bmiba & 0x01) == 0) {
483: IOLog("%s: PCI memory range 0x%02x (0x%08lx) is not an I/O range\n",
484: [self name], PIIX_BMIBA, bmiba);
485: return NO;
486: }
487:
488: _bmRegs = bmiba & PIIX_BM_MASK;
489:
490: if (_bmRegs == 0) // uninitialized range
491: return NO;
492:
493: if (_ideChannel == PCI_CHANNEL_SECONDARY)
494: _bmRegs += PIIX_BM_OFFSET;
495:
496: /*
497: * Add this range to our device description's port range list.
498: */
499: io_range[0] = [devDesc portRangeList][0];
500: io_range[1].start = _bmRegs;
501: io_range[1].size = PIIX_BM_SIZE;
502: if ([devDesc setPortRangeList:io_range num:2] != IO_R_SUCCESS) {
503: IOLog("%s: setPortRangeList failed\n", [self name]);
504: return NO;
505: }
506:
507: return YES;
508: }
509:
510: /*
511: * Method: PIIXInitPRDTable
512: *
513: * Purpose:
514: * Initialize a "page-aligned" page of memory for the PRD descriptors
515: * used by the bus master IDE controller.
516: *
517: * FIXME: Need to free the _prdTable memory.
518: */
519: - (BOOL) PIIXInitPRDTable
520: {
521: _prdTable.size = PAGE_SIZE;
522: _prdTable.ptr = (void *)IOMallocPage(
523: _prdTable.size,
524: &_prdTable.ptrReal,
525: &_prdTable.sizeReal
526: );
527:
528: /*
529: * _prdTable->ptr should now points to a physically contiguous block
530: * of PAGE_SIZE bytes.
531: */
532: if (_prdTable.ptr == NULL)
533: return NO;
534:
535: /*
536: * cache the physical address of the descriptor table to _tablePhyAddr.
537: */
538: if (IOPhysicalFromVirtual(IOVmTaskSelf(), (vm_address_t)_prdTable.ptr,
539: &_tablePhyAddr) != IO_R_SUCCESS) {
540: IOFree(_prdTable.ptrReal, _prdTable.sizeReal);
541: return NO;
542: }
543:
544: bzero(_prdTable.ptr, _prdTable.size);
545: return YES;
546: }
547:
548: /*
549: * Method: PIIXReportTimings:slaveTiming:isPrimary:
550: *
551: * Purpose:
552: * Log the drive timings set in the two PIIX timing registers.
553: * The units for the values are in PCI clocks.
554: */
555: - (void) PIIXReportTimings:(piix_idetim_u)tim
556: slaveTiming:(piix_sidetim_u)stim
557: isPrimary:(BOOL)primary
558: {
559: if (!_ide_debug)
560: return;
561:
562: IOLog("%s: Drive 0: ISP:%d Clks RCT:%d Clks\n",
563: [self name],
564: PIIX_ISP_TO_CLK(tim.bits.isp),
565: PIIX_RCT_TO_CLK(tim.bits.rct));
566: #if 0
567: IOLog("%s: Drive 0 Fast timing DMA only: %s\n", [self name],
568: tim.bits.dte0 ? "on" : "off");
569: IOLog("%s: Drive 0 Prefetch and Posting: %s\n", [self name],
570: tim.bits.ppe0 ? "on" : "off");
571: IOLog("%s: Drive 0 IORDY sample enable : %s\n", [self name],
572: tim.bits.ie0 ? "on" : "off");
573: IOLog("%s: Drive 0 Fast timing enable : %s\n", [self name],
574: tim.bits.time0 ? "on" : "off");
575: #endif 0
576: IOLog("%s: Drive 1: ISP:%d Clks RCT:%d Clks\n", [self name],
577: tim.bits.sitre ?
578: (primary ?
579: PIIX_ISP_TO_CLK(stim.bits.pisp1) :
580: PIIX_ISP_TO_CLK(stim.bits.sisp1)) :
581: PIIX_ISP_TO_CLK(tim.bits.isp),
582: tim.bits.sitre ?
583: (primary ?
584: PIIX_RCT_TO_CLK(stim.bits.prct1) :
585: PIIX_RCT_TO_CLK(stim.bits.srct1)) :
586: PIIX_RCT_TO_CLK(tim.bits.rct));
587: #if 0
588: IOLog("%s: Drive 1 Fast timing DMA only: %s\n", [self name],
589: tim.bits.dte1 ? "on" : "off");
590: IOLog("%s: Drive 1 Prefetch and Posting: %s\n", [self name],
591: tim.bits.ppe1 ? "on" : "off");
592: IOLog("%s: Drive 1 IORDY sample enable : %s\n", [self name],
593: tim.bits.ie1 ? "on" : "off");
594: IOLog("%s: Drive 1 Fast timing enable : %s\n", [self name],
595: tim.bits.time1 ? "on" : "off");
596: #endif 0
597: }
598:
599: /*
600: * Method: setPCIControllerCapabilities
601: *
602: * Purpose:
603: * Based on the transfer modes and types for both IDE drives, setup the
604: * controller to support those modes.
605: *
606: */
607: - (BOOL) setPCIControllerCapabilitiesForDrives:(driveInfo_t *)drives
608: {
609: IOPCIConfigSpace configSpace;
610:
611: if (_controllerID == PCI_ID_NONE)
612: return NO;
613:
614: [self getPCIConfigSpace:&configSpace];
615:
616: switch (_controllerID) {
617: case PCI_ID_PIIX:
618: case PCI_ID_PIIX3:
619: case PCI_ID_PIIX4:
620: [self PIIXComputePCIConfigSpace:&configSpace forDrives:drives];
621: break;
622: default:
623: return NO;
624: }
625:
626: [self setPCIConfigSpace:&configSpace];
627: return YES;
628: }
629:
630: /*
631: * Method: computePCIConfigSpaceForPIIX:modes:
632: *
633: * Purpose:
634: * Set the IDETIM and the SIDETIM IDE timing registers based on the
635: * PIO modes supported by the two drives on the IDE channel.
636: */
637: - (void) PIIXComputePCIConfigSpace:(IOPCIConfigSpace *)configSpace
638: forDrives:(driveInfo_t *)drv
639: {
640: u_char *pci_space = (u_char *)configSpace;
641: piix_idetim_u *idetim;
642: piix_sidetim_u *sidetim;
643: piix_udmactl_u *udmactl;
644: piix_udmatim_u *udmatim;
645: unsigned char modeDrive0;
646: unsigned char modeDrive1;
647: u_char isp, rct;
648:
649: if (MAX_IDE_DRIVES != 2)
650: return;
651:
652: switch (_ideChannel) {
653: case PCI_CHANNEL_PRIMARY:
654: idetim = (piix_idetim_u *)&pci_space[PIIX_IDETIM];
655: break;
656: case PCI_CHANNEL_SECONDARY:
657: idetim = (piix_idetim_u *)&pci_space[PIIX_IDETIM_S];
658: break;
659: default:
660: IOLog("%s: PIIX: Unknown IDE channel\n", [self name]);
661: return;
662: }
663: sidetim = (piix_sidetim_u *)&pci_space[PIIX_SIDETIM];
664: udmactl = (piix_udmactl_u *)&pci_space[PIIX_UDMACTL];
665: udmatim = (piix_udmatim_u *)&pci_space[PIIX_UDMATIM];
666:
667: modeDrive0 = ata_mode_to_num(drv[0].transferMode);
668: modeDrive1 = ata_mode_to_num(drv[1].transferMode);
669:
670: /* Enable slave timing if timings are different and
671: * a slave device is present.
672: */
673: idetim->bits.sitre = 0;
674: isp = PIIXGetISPForMode(modeDrive0, drv[0].transferType);
675: rct = PIIXGetRCTForMode(modeDrive0, drv[0].transferType);
676:
677: if ((PIIXGetCycleForMode(modeDrive0, drv[0].transferType) !=
678: PIIXGetCycleForMode(modeDrive1, drv[1].transferType)) &&
679: (drv[1].ideInfo.type != 0)) {
680: if (_controllerID == PCI_ID_PIIX) {
681: /* Do not have the luxury of separate timing register for
682: * drive 0 and drive 1. Use the minimum of the two PIO modes.
683: * Or, the max of the two timings.
684: */
685: isp = MAX(PIIXGetISPForMode(modeDrive0, drv[0].transferType),
686: PIIXGetISPForMode(modeDrive1, drv[1].transferType));
687: rct = MAX(PIIXGetRCTForMode(modeDrive0, drv[0].transferType),
688: PIIXGetRCTForMode(modeDrive1, drv[1].transferType));
689: }
690: else
691: idetim->bits.sitre = 1; // enable slave timing
692: }
693:
694: /*
695: * Reset all performance tuning bits and disable UDMA.
696: */
697: idetim->word &= 0xc000;
698: switch (_ideChannel) {
699: case PCI_CHANNEL_PRIMARY:
700: udmactl->bits.psde0 = 0;
701: udmactl->bits.psde1 = 0;
702: break;
703: default:
704: udmactl->bits.ssde0 = 0;
705: udmactl->bits.ssde1 = 0;
706: }
707:
708: /*
709: * Set the timings for drive 0 (master).
710: */
711: if (drv[0].ideInfo.type == 0) {
712: IOLog("%s: Drive 0 is not present\n", [self name]);
713: return;
714: }
715:
716: /*
717: * Set timings for Drive 0 (Master drive).
718: */
719: if (drv[0].transferType == IDE_TRANSFER_ULTRA_DMA) {
720: if (modeDrive0 > 2) modeDrive0 = 2;
721: switch (_ideChannel) {
722: case PCI_CHANNEL_PRIMARY:
723: udmactl->bits.psde0 = 1;
724: udmatim->bits.pct0 = modeDrive0;
725: break;
726: case PCI_CHANNEL_SECONDARY:
727: udmactl->bits.ssde0 = 1;
728: udmatim->bits.sct0 = modeDrive0;
729: break;
730: default:
731: break;
732: }
733: }
734: idetim->bits.isp = isp;
735: idetim->bits.rct = rct;
736:
737: /* Set timings for drive 1 (Slave drive).
738: */
739: if (drv[1].transferType == IDE_TRANSFER_ULTRA_DMA) {
740: if (modeDrive1 > 2) modeDrive1 = 2;
741: switch (_ideChannel) {
742: case PCI_CHANNEL_PRIMARY:
743: udmactl->bits.psde1 = 1;
744: udmatim->bits.pct1 = modeDrive1;
745: break;
746: case PCI_CHANNEL_SECONDARY:
747: udmactl->bits.ssde1 = 1;
748: udmatim->bits.sct1 = modeDrive1;
749: break;
750: default:
751: break;
752: }
753: }
754: if (idetim->bits.sitre) {
755: isp = PIIXGetISPForMode(modeDrive1, drv[1].transferType);
756: rct = PIIXGetRCTForMode(modeDrive1, drv[1].transferType);
757: if (_ideChannel == PCI_CHANNEL_PRIMARY) {
758: sidetim->bits.pisp1 = isp;
759: sidetim->bits.prct1 = rct;
760: }
761: else {
762: sidetim->bits.sisp1 = isp;
763: sidetim->bits.srct1 = rct;
764: }
765: }
766:
767: /*
768: * Enable fast timings. Turn on IORDY sampling always?
769: */
770: idetim->bits.time0 = 1;
771: idetim->bits.ppe0 = 1;
772: idetim->bits.ie0 = 1;
773: if (drv[1].ideInfo.type != 0) {
774: idetim->bits.time1 = 1;
775: idetim->bits.ppe1 = 1;
776: idetim->bits.ie1 = 1;
777: }
778:
779: /*
780: * For DMA, disable fast timing for PIO.
781: */
782: if (drv[0].transferType != IDE_TRANSFER_PIO)
783: idetim->bits.dte0 = 1;
784: if (drv[1].transferType != IDE_TRANSFER_PIO)
785: idetim->bits.dte1 = 1;
786:
787: [self PIIXReportTimings:*idetim slaveTiming:*sidetim
788: isPrimary:(_ideChannel == PCI_CHANNEL_PRIMARY)];
789:
790: return;
791: }
792:
793: /*************************************************************************
794: *
795: * Intel PIIX/PIIX3/PIIX4 Bus-Mastering IDE DMA support
796: *
797: *************************************************************************/
798:
799: /*
800: * Function: PIIXVirtualToPhysical
801: *
802: * Similar to IOPhysicalFromVirtual but with no SPLVM/SPLX and locking.
803: */
804: static __inline__ vm_offset_t
805: PIIXVirtualToPhysical(struct vm_map *map, vm_offset_t vaddr)
806: {
807: return (vm_offset_t)pmap_resident_extract(
808: (pmap_t)vm_map_pmap_EXTERNAL(map),
809: vaddr);
810: }
811:
812: /*
813: * Function: PIIXStartDMA
814: *
815: * Purpose:
816: * Start the bus master by writing a 1 to the SSBM bit in BMICX register.
817: *
818: * Argument:
819: * piix_base - base address of the I/O space mapped bus master registers
820: */
821: static __inline__ void
822: PIIXStartDMA(u_short piix_base)
823: {
824: piix_bmicx_u piix_cmd;
825:
826: /*
827: * Engage the bus master by writing 1 to the start bit in the
828: * Command Register.
829: */
830: piix_cmd.byte = inb(piix_base + PIIX_BMICX);
831: piix_cmd.bits.ssbm = 1;
832: outb(piix_base + PIIX_BMICX, piix_cmd.byte);
833: }
834:
835: /*
836: * Function: PIIXStopDMA
837: *
838: * Purpose:
839: * Stop the bus master by clearing the SSBM bit in BMICX register.
840: *
841: * Argument:
842: * piix_base - base address of the I/O space mapped bus master registers
843: */
844: static __inline__ void
845: PIIXStopDMA(u_short piix_base)
846: {
847: piix_bmicx_u piix_cmd;
848:
849: /*
850: * Stop the bus master by writing 0 to the start bit in the
851: * Command Register.
852: */
853: piix_cmd.byte = inb(piix_base + PIIX_BMICX);
854: piix_cmd.bits.ssbm = 0;
855: outb(piix_base + PIIX_BMICX, piix_cmd.byte);
856: }
857:
858: /*
859: * Function: PIIXGetStatus
860: *
861: * Purpose:
862: * Return the PIIX BMISX (bus master IDE status register).
863: *
864: * Argument:
865: * piix_base - base address of the I/O space mapped bus master registers
866: */
867: static __inline__ u_char
868: PIIXGetStatus(u_short piix_base)
869: {
870: return (inb(piix_base + PIIX_BMISX));
871: }
872:
873: /*
874: * Function: PIIXSetupPRDTable
875: *
876: * Purpose:
877: * Setup the PRD (descriptor) table for the current IDE transfer.
878: * This table must be aligned on a DWord (4 byte) boundary.
879: *
880: * Arguments:
881: * table - points to the start of the PRD table
882: * size - max number of PRD entries that the table can hold
883: * vaddr - virtual address of the start of memory buffer
884: * size - size of memory buffer in bytes
885: * map - vm_map for the memory buffer
886: *
887: * Return:
888: * YES: table is setup and ready for use
889: * NO : table full or alignment error
890: *
891: */
892: static __inline__ BOOL
893: PIIXSetupPRDTable(piix_prd_t *table, u_int table_size, vm_offset_t vaddr,
894: u_int size, struct vm_map *map)
895: {
896: vm_offset_t vaddr_next;
897: vm_offset_t paddr;
898: vm_offset_t paddr_next;
899: vm_offset_t paddr_start;
900: const char *name = "PIIXSetupPRDTable";
901: u_int len_prd;
902: u_int index;
903:
904: #ifdef DEBUG
905: piix_prd_t *table_saved = table;
906: #endif DEBUG
907:
908: ddm_ide_dma(" PIIXSetupPRDTable: vaddr:%08x size:%d\n",
909: (u_int)vaddr, (u_int)size, 3, 4, 5);
910:
911: if (vaddr & (PIIX_BUF_ALIGN - 1)) {
912: IOLog("%s: buffer is not %d byte aligned\n", name, PIIX_BUF_ALIGN);
913: return NO;
914: }
915:
916: if (size == 0) {
917: IOLog("%s: zero length DMA buffer\n", name);
918: return NO;
919: }
920:
921: index = len_prd = 0;
922: paddr = PIIXVirtualToPhysical(map, vaddr);
923: paddr_start = paddr;
924: do {
925: u_int len;
926:
927: vaddr_next = trunc_page(vaddr) + PAGE_SIZE; // next virtual page
928: paddr_next = trunc_page(paddr) + PAGE_SIZE; // next phys page
929: vaddr = vaddr_next;
930:
931: len = paddr_next - paddr; // length to transfer in this page
932: if (len > size) len = size; // take the minimum
933: size -= len; // decrement total remaining bytes
934: len_prd += len; // increment current PRD counter
935:
936: /*
937: * If there are more bytes remaining, try to append the next
938: * page into the same PRD. We must check that the next page
939: * is physically contiguous with the current one.
940: *
941: * Each PRD cannot cross 64K boundary, and is limited to 64K per PRD.
942: */
943: if (size &&
944: (paddr_next == (paddr = PIIXVirtualToPhysical(map, vaddr))) &&
945: ((paddr_start & ~(PIIX_BUF_BOUND-1))==(paddr & ~(PIIX_BUF_BOUND-1))) &&
946: (len_prd <= (PIIX_BUF_LIMIT - PAGE_SIZE))) {
947: continue;
948: }
949:
950: /*
951: * Setup PRD entry
952: *
953: * For the length field in PRD, 0 is used to denote the max
954: * transfer size of 64K.
955: */
956: table->base = paddr_start;
957: table->count = (len_prd == PIIX_BUF_LIMIT) ? 0 : len_prd;
958: table->eot = 0;
959: table++;
960:
961: len_prd = 0;
962: paddr_start = paddr;
963:
964: } while (size && (++index < table_size));
965:
966: if (size) {
967: IOLog("%s: PRD table exhausted\n", name);
968: return NO;
969: }
970:
971: /*
972: * Set the 'end-of-table' bit on the last PRD entry.
973: */
974: --table;
975: table->eot = 1;
976:
977: #ifdef DEBUG
978: {
979: int i = 0;
980: u_int *ip = (u_int *)&table_saved[0];
981: do {
982: ddm_ide_dma(" table[%d] %08x:%08x\n", i, *ip, *(ip+1), 4, 5);
983: ip += 2;
984: } while (i++ < index);
985: }
986: #endif DEBUG
987:
988: return YES;
989: }
990:
991: /*
992: * Function: PIIXPrepareDMA
993: *
994: * Purpose:
995: * Prepare the PIIX bus master for a DMA transfer.
996: *
997: * Arguments:
998: * piix_base - base address of the I/O space mapped bus master registers
999: * table - points to the start of the PRD table
1000: * tableAddr - physical address of the table
1001: * isRead - YES for read transfers (from device to host)
1002: */
1003: static __inline__ BOOL
1004: PIIXPrepareDMA(u_short piix_base, u_int tableAddr, BOOL isRead)
1005: {
1006: piix_bmicx_u piix_cmd;
1007: piix_bmisx_u piix_status;
1008:
1009: /*
1010: * Provide the starting address of the PRD table by loading the
1011: * PRD Table Pointer Register.
1012: *
1013: * For some reason, outl(piix_base + PIIX_BMIDTPX, tableAddr)
1014: * will only write the lower 16-bit WORD. That's why we use
1015: * two outw instructions.
1016: */
1017: outw(piix_base + PIIX_BMIDTPX, tableAddr & 0xffff);
1018: outw(piix_base + PIIX_BMIDTPX + 2, (tableAddr >> 16) & 0xffff);
1019:
1020: /*
1021: * Set the R/W bit depending on the direction of the transfer.
1022: * The controller is also STOP'ed.
1023: *
1024: * Arghh!!! Why does the Intel PIIX3 and PIIX4 doc have this backwards?
1025: */
1026: piix_cmd.byte = 0;
1027: piix_cmd.bits.rwcon = isRead ? 1 : 0;
1028: outb(piix_base + PIIX_BMICX, piix_cmd.byte);
1029:
1030: /*
1031: * Clear interrupt and error bits in the Status Register.
1032: */
1033: piix_status.byte = inb(piix_base + PIIX_BMISX);
1034: piix_status.bits.err = piix_status.bits.ideints = 1;
1035: // piix_status.bits.dma0cap = piix_status.bits.dma1cap = 1;
1036: outb(piix_base + PIIX_BMISX, piix_status.byte);
1037:
1038: return YES;
1039: }
1040:
1041: /*
1042: * Method: PIIXInit
1043: *
1044: * Purpose:
1045: * Initializes the PIIX controller.
1046: */
1047: - (void) PIIXInit
1048: {
1049: return (PIIXStopDMA(_bmRegs));
1050: }
1051:
1052: /*
1053: * Even if an interrupt is missed, consider the transfer operation
1054: * successful if the PIIX status flags says so.
1055: */
1056: #define TRUST_PIIX 1
1057:
1058: /*
1059: * Method: PIIXPerformDMA
1060: *
1061: * Purpose:
1062: * Program the PIIX controller to perform DMA READ/WRITE transfers
1063: * based on the transfer request ideIoReq. The entire transfer is
1064: * translated into one or more PRD entries in the PRD table. We will
1065: * get a single interrupt when the entire transfer is complete.
1066: *
1067: * Note:
1068: * The PIIX status register should have bit 2 and bit 0 set at the
1069: * conclusion of the transfer. This corresponds to the case when the
1070: * IDE device generated an interrupt and the size of the PRD is equal
1071: * to the IDE device transfer size.
1072: *
1073: * If bit 1 is set, meaning that the controller encountered a target
1074: * or master abort, it is very likely that we told it to DMA to/from
1075: * an invalid piece of memory. Perhaps due to an incorrect virtual
1076: * to physical map conversion.
1077: */
1078: - (ide_return_t) performDMA:(ideIoReq_t *)ideIoReq
1079: {
1080: ideRegsVal_t *ideRegs = &(ideIoReq->regValues);
1081: ideRegsAddrs_t *rp = &_ideRegsAddrs;
1082: unsigned char status;
1083: piix_bmisx_u piix_status;
1084: ide_return_t rtn = IDER_SUCCESS;
1085: unsigned cmd = ideIoReq->cmd;
1086:
1087: ddm_ide_dma("DMA block:%d count:%d read:%d map:%d rp:%x\n",
1088: ideIoReq->block,
1089: ideIoReq->blkcnt,
1090: (ideIoReq->cmd == IDE_READ_DMA),
1091: ideIoReq->map,
1092: rp->data);
1093:
1094: if ((cmd != IDE_READ_DMA) && (cmd != IDE_WRITE_DMA)) {
1095: IOLog("%s: ideDmaRwCommon: unknown command %d\n", [self name], cmd);
1096: return IDER_REJECT;
1097: }
1098:
1099: /*
1100: * wait for BSY = 0 and DRDY = 1
1101: */
1102: rtn = [self waitForDeviceReady];
1103: if (rtn != IDER_SUCCESS) {
1104: IOLog("%s: drive not ready\n", [self name]);
1105: return (rtn);
1106: }
1107:
1108: /*
1109: * Set up PRD descriptor table
1110: */
1111: if (PIIXSetupPRDTable(_prdTable.ptr,
1112: PIIX_DT_BOUND/sizeof(piix_prd_t),
1113: (vm_offset_t)ideIoReq->addr,
1114: ideIoReq->blkcnt * IDE_SECTOR_SIZE,
1115: (struct vm_map *)ideIoReq->map) == NO) {
1116: return NO;
1117: }
1118:
1119: /*
1120: * Prepare the PIIX controller for the current transfer.
1121: */
1122: if (PIIXPrepareDMA(_bmRegs, _tablePhyAddr,
1123: (ideIoReq->cmd == IDE_READ_DMA)) == NO) {
1124: IOLog("%s: PIIXPrepareDMA error\n", [self name]);
1125: return IDER_CMD_ERROR;
1126: }
1127:
1128: /*
1129: * Program the drive (task file).
1130: * Recall that _driveNum must be set prior to calling logToPhys.
1131: * This is already done in the method ideExecuteCmd which calls
1132: * this method. testDMA also calls this method with _driveNum set.
1133: */
1134: *ideRegs = [self logToPhys:ideIoReq->block numOfBlocks:ideIoReq->blkcnt];
1135: outb(rp->drHead, ideRegs->drHead);
1136: outb(rp->sectNum, ideRegs->sectNum);
1137: outb(rp->sectCnt, ideRegs->sectCnt);
1138: outb(rp->cylLow, ideRegs->cylLow);
1139: outb(rp->cylHigh, ideRegs->cylHigh);
1140:
1141: ddm_ide_dma(
1142: "DMA drHead:%02x sectNum:%02x sectCnt:%02x cylLow:%02x cylHigh:%02x\n",
1143: ideRegs->drHead,
1144: ideRegs->sectNum,
1145: ideRegs->sectCnt,
1146: ideRegs->cylLow,
1147: ideRegs->cylHigh);
1148:
1149: /*
1150: * Issue DMA READ/WRITE command to drive.
1151: */
1152: // [self enableInterrupts];
1153: // [self clearInterrupts];
1154: outb(rp->command, cmd);
1155:
1156: /*
1157: * Start the PIIX bus master.
1158: */
1159: PIIXStartDMA(_bmRegs);
1160:
1161: /* Wait for interrupt to signal the completion of the transfer.
1162: */
1163: rtn = [self ideWaitForInterrupt:cmd ideStatus:&status];
1164: piix_status.byte = PIIXGetStatus(_bmRegs);
1165: PIIXStopDMA(_bmRegs);
1166:
1167: #ifdef TRUST_PIIX
1168: if ((piix_status.byte & PIIX_STATUS_MASK) == PIIX_STATUS_OK) {
1169:
1170: if (rtn != IDER_SUCCESS) {
1171: /* Interrupt timed-out, but PIIX claims that transaction
1172: * was completed without errors.
1173: * This may require more testing. Always trust PIIX?
1174: * First, read status from the drive.
1175: */
1176: if ((rtn = [self waitForNotBusy]) != IDER_SUCCESS)
1177: return IDER_CMD_ERROR;
1178: status = inb(rp->status);
1179: }
1180: #else
1181: if ((rtn == IDER_SUCCESS) && ((piix_status.byte & PIIX_STATUS_MASK) ==
1182: PIIX_STATUS_OK)) {
1183: #endif TRUST_PIIX
1184:
1185: if (status & (ERROR | WRITE_FAULT)) {
1186: [self getIdeRegisters:ideRegs Print:"DMA error"];
1187: return IDER_CMD_ERROR;
1188: }
1189:
1190: if (status & ERROR_CORRECTED) {
1191: IOLog("%s: Error during data transfer (corrected).\n",
1192: [self name]);
1193: }
1194: }
1195: else {
1196: [self getIdeRegisters:ideRegs Print:NULL];
1197: IOLog("%s: PIIX status:0x%02x error code:%d\n",
1198: [self name], piix_status.byte, rtn);
1199: rtn = IDER_CMD_ERROR;
1200: }
1201:
1202: ddm_ide_dma(
1203: "END drHead:%02x sectNum:%02x sectCnt:%02x cylLow:%02x cylHigh:%02x\n",
1204: inb(rp->drHead),
1205: inb(rp->sectNum),
1206: inb(rp->sectCnt),
1207: inb(rp->cylLow),
1208: inb(rp->cylHigh));
1209:
1210: return (rtn);
1211: }
1212:
1213: #define MAX_BUSY_WAIT (1000*100)
1214:
1215: /*
1216: * Perform DMA transfers for ATAPI devices.
1217: */
1218: - (sc_status_t) performATAPIDMA:(atapiIoReq_t *)atapiIoReq
1219: buffer:(void *)buffer
1220: client:(struct vm_map *)client
1221: {
1222: piix_bmisx_u piix_status;
1223: unsigned char cmd = atapiIoReq->atapiCmd[0];
1224: ide_return_t rtn;
1225: unsigned char status;
1226: ideRegsAddrs_t *rp = &_ideRegsAddrs;
1227: int i;
1228:
1229: //IOLog("DMA transfer\n");
1230:
1231: atapiIoReq->bytesTransferred = 0;
1232:
1233: /*
1234: * Set up PRD descriptor table
1235: */
1236: if (PIIXSetupPRDTable(_prdTable.ptr,
1237: PIIX_DT_BOUND/sizeof(piix_prd_t),
1238: (vm_offset_t)buffer,
1239: atapiIoReq->maxTransfer,
1240: client) == NO)
1241: {
1242: atapiIoReq->scsiStatus = STAT_CHECK;
1243: return SR_IOST_CMDREJ;
1244: }
1245:
1246: if (PIIXPrepareDMA(_bmRegs, _tablePhyAddr, atapiIoReq->read) == NO) {
1247: IOLog("%s: PIIXPrepareDMA error\n", [self name]);
1248: atapiIoReq->scsiStatus = STAT_CHECK;
1249: return SR_IOST_CMDREJ;
1250: }
1251:
1252: /*
1253: * Start the PIIX bus master.
1254: */
1255: PIIXStartDMA(_bmRegs);
1256:
1257: if (atapiIoReq->timeout > IDE_INTR_TIMEOUT) {
1258: u_int current_timeout = [self interruptTimeOut];
1259:
1260: //IOLog("using SCSI timeout:%d\n", atapiIoReq->timeout);
1261: [self setInterruptTimeOut:atapiIoReq->timeout];
1262: rtn = [self ideWaitForInterrupt:cmd ideStatus:&status];
1263: [self setInterruptTimeOut:current_timeout];
1264: }
1265: else {
1266: rtn = [self ideWaitForInterrupt:cmd ideStatus:&status];
1267: }
1268:
1269: piix_status.byte = PIIXGetStatus(_bmRegs);
1270: PIIXStopDMA(_bmRegs);
1271:
1272: /*
1273: * This is stupid but the Chinon drive fires off an interrupt first
1274: * and then updates the status register. It appears that any drive
1275: * based on Western Digital chipset will do this. At any rate, this
1276: * code is harmless and should be left here.
1277: */
1278: for (i = 0; i < MAX_BUSY_WAIT; i++) {
1279: if (status & BUSY)
1280: IODelay(10);
1281: else
1282: break;
1283: status = inb(_ideRegsAddrs.status);
1284: }
1285:
1286: #ifdef TRUST_PIIX
1287: if ((piix_status.byte & PIIX_STATUS_MASK) == PIIX_STATUS_OK) {
1288: if (rtn != IDER_SUCCESS) {
1289: /* Interrupt timed-out, but PIIX claims that transaction
1290: * was completed without errors.
1291: * This may require more testing. Always trust PIIX?
1292: * First, read status from the drive.
1293: */
1294: if ((rtn = [self waitForNotBusy]) != IDER_SUCCESS) {
1295: IOLog("%s: FATAL: ATAPI Drive: %d Command %x failed.\n",
1296: [self name], _driveNum, atapiIoReq->atapiCmd[0]);
1297: [self getIdeRegisters:NULL Print:"ATAPI DMA"];
1298: IOLog("%s: transfer size: %d\n",
1299: [self name], atapiIoReq->maxTransfer);
1300: [self atapiSoftReset:_driveNum];
1301: atapiIoReq->scsiStatus = STAT_CHECK;
1302: return SR_IOST_CHKSNV;
1303: }
1304: status = inb(rp->status);
1305: }
1306: #else
1307: if ((rtn == IDER_SUCCESS) && ((piix_status.byte & PIIX_STATUS_MASK) ==
1308: PIIX_STATUS_OK)) {
1309: #endif TRUST_PIIX
1310:
1311: if (status & ERROR) {
1312: atapiIoReq->scsiStatus = STAT_CHECK;
1313: return SR_IOST_CHKSNV;
1314: }
1315: }
1316: else {
1317: [self getIdeRegisters:NULL Print:"ATAPI DMA"];
1318: IOLog("%s: PIIX status:0x%02x error code:%d\n",
1319: [self name], piix_status.byte, rtn);
1320: IOLog("%s: transfer size: %d\n", [self name], atapiIoReq->maxTransfer);
1321: [self atapiSoftReset:_driveNum];
1322: atapiIoReq->scsiStatus = STAT_CHECK;
1323: return SR_IOST_CHKSNV;
1324: }
1325:
1326: atapiIoReq->bytesTransferred = atapiIoReq->maxTransfer;
1327: atapiIoReq->scsiStatus = STAT_GOOD;
1328: return SR_IOST_GOOD;
1329: }
1330:
1331: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.