Jump to content

Location of Kernel Panic Logs


KirbySaysHi
 Share

48 posts in this topic

Recommended Posts

social, for the most part, this topic seems pretty relevant.

 

I really think the problem is with the flippin jmicron controller, coupled with having more than 4gb of ram. I have a pretty good feeling that if that controller is disabled, we won't have these problems anymore.

 

Also, I've tried using the JMicron kext, and not using it. The kernel panics happened either way, except that the panic would list JMicron.kext as the culprit, and not AppleVIAATA.kext.

Link to comment
Share on other sites

social, for the most part, this topic seems pretty relevant.

 

I really think the problem is with the flippin jmicron controller, coupled with having more than 4gb of ram. I have a pretty good feeling that if that controller is disabled, we won't have these problems anymore.

 

Also, I've tried using the JMicron kext, and not using it. The kernel panics happened either way, except that the panic would list JMicron.kext as the culprit, and not AppleVIAATA.kext.

 

ok, well I managed to eliminate the problem (I'm pretty sure). To do this, I did two things:

 

I unplugged my IDE Hard drive, and I deleted JMicronATA.kext.

 

I'm not completely sure, because I only ran for about 15 minutes, but my cpu and ram was completely maxed out the entire time.

 

This makes me sad, because I just found 2 250GB IDE hard drives lying around. :(

 

Time to see if pluggin in the IDE HDD will cause the panics again.

 

Can we debug this problem using the source code? How much experience do you have with coding?

Link to comment
Share on other sites

Can we debug this problem using the source code? How much experience do you have with coding?

I could probably do it; I have experience writing linux drivers. However.. I've never worked with BSD and OS X. It will probably take a long time and quite an effort. Maybe if we got several people and combined the effort it would be easier. I would certainly be willing to give it a shot.

Link to comment
Share on other sites

I could probably do it; I have experience writing linux drivers. However.. I've never worked with BSD and OS X. It will probably take a long time and quite an effort. Maybe if we got several people and combined the effort it would be easier. I would certainly be willing to give it a shot.

 

Thank you!

 

I am not asking anyone to go out and do this for us. I would actually like to do it myself, for the fun and the learning. I think working together is a good idea.

 

When I first encountered this problem, I found the place in the source code where the kernel panic was "called". I couldn't really understand the code, so here it is:

 

IOPhysicalAddress
IOGeneralMemoryDescriptor::getPhysicalSegment(IOByteCount offset, IOByteCount *lengthOfSegment)
{
IOReturn		  ret;
IOByteCount	   length  = 0;
addr64_t		  address = 0;

//  assert(offset <= _length);

if (offset < _length) // (within bounds?)
{
IOMDDMAWalkSegmentState _state;
IOMDDMAWalkSegmentArgs * state = (IOMDDMAWalkSegmentArgs *) &_state;

state->fOffset = offset;
state->fLength = _length - offset;
state->fMapped = true;

ret = dmaCommandOperation(
	kIOMDFirstSegment, _state, sizeof(_state));

if ((kIOReturnSuccess != ret) && (kIOReturnOverrun != ret))
	DEBG("getPhysicalSegment dmaCommandOperation(%lx), %p, offset %qx, addr %qx, len %qx\n", 
				ret, this, state->fOffset,
				state->fIOVMAddr, state->fLength);
if (kIOReturnSuccess == ret)
{
	address = state->fIOVMAddr;
	length  = state->fLength;
}

	if (!address)
		length = 0;
}

if ((address + length) > 0x100000000ULL)
{
panic("getPhysicalSegment() out of 32b range 0x%qx, len 0x%lx, class %s",
		address, length, (getMetaClass())->getClassName());
}

if (lengthOfSegment)
	*lengthOfSegment = length;

return ((IOPhysicalAddress) address);
}

 

the 'panic("...' is what causes the kernel panic. I had the idea that instead of panicing, I would modify the source code to call getPhysicalSegment64 instead. However, this gave page fault kernel panics. I think this means that something is calling memory that isn't just out of 32 bit range, but is non-existent. Even the 64 bit function can't find it. Here is what the modified source code looked like, including the getPhysicalSegment64() following it:

 

IOPhysicalAddress
IOGeneralMemoryDescriptor::getPhysicalSegment(IOByteCount offset, IOByteCount *lengthOfSegment)
{
IOReturn		  ret;
IOByteCount	   length  = 0;
addr64_t		  address = 0;

...

if ((address + length) > 0x100000000ULL)
{
/*	panic("getPhysicalSegment() out of 32b range 0x%qx, len 0x%lx, class %s",
		address, length, (getMetaClass())->getClassName()); */
	return ((IOPhysicalAddress) getPhysicalSegment64(offset, lengthOfSegment));	
}

if (lengthOfSegment)
	*lengthOfSegment = length;

return ((IOPhysicalAddress) address);
}

addr64_t
IOMemoryDescriptor::getPhysicalSegment64(IOByteCount offset, IOByteCount *lengthOfSegment)
{
IOPhysicalAddress phys32;
IOByteCount		  length;
addr64_t 		  phys64;
IOMapper *		mapper = 0;

phys32 = getPhysicalSegment(offset, lengthOfSegment);
if (!phys32)
return 0;

if (gIOSystemMapper)
mapper = gIOSystemMapper;

if (mapper)
{
IOByteCount origLen;

phys64 = mapper->mapAddr(phys32);
origLen = *lengthOfSegment;
length = page_size - (phys64 & (page_size - 1));
while ((length < origLen)
	&& ((phys64 + length) == mapper->mapAddr(phys32 + length)))
	length += page_size;
if (length > origLen)
	length = origLen;

*lengthOfSegment = length;
}
else
phys64 = (addr64_t) phys32;

return phys64;
}

 

here is what my kernel panics look like. The first one is with the unmodified kernel, the second one is with that source code modification:

 

panic(cpu 0 caller 0x00427BC7): "getPhysicalSegment() out of 32b range 0x10e1e0000, len 0x1000, class IOGeneralMemoryDescriptor"@/SourceCache/xnu/xnu-1228.0.2/iokit/Kernel/IOMemoryDescriptor.cpp:1471
Debugger called: <panic>
Backtrace, Format - Frame : Return Address (4 potential args on stack)

16 lines of {censored}


	Backtrace continues...
Kernel loadable modules in backtrace (wih dependencies):
	com.apple.iokit.IOATABlockStorage(1.4.4)A0x5b490000->0x52499fff
		dependency: com.apple.iokit.IOStorageFamily(1.5.2)@0x5aac2000
		dependency: com.apple.iokit.IOATAFamily(1.7.1f4)@0x5ae2d000
	com.apple.driver.AppleVIAATA(1.0.2)@0x5b048000->0x5b04dfff
		dependency: com.apple.iokit.IOPCIFamily(2.4)@0x54670000
		dependency: com.apple.iokit.IOATAFamily(1.7.1f4)@0x5ae2d000
	com.apple.iokit.IOATAFamily(1.7.1f4)0x5ae2d000->0x5ae39fff
	com.apple/iokit.IOStorageFamily(1.5.2)@0x5aac2000->0x5aad9fff

BSD process name corresponding to current thread: mds

Mac OS version:
9B18

Kernel version:
Darwin Kernel Version 9.1.0: Wed Oct 31 17:46:22 PDT 2007; root:xnu-1228.0.2~1/RELEASE_I386
Sstem model name: P35-DS3P


================++++++++++++++++++++++=====================



panic(cpu 1 caller 0x001a7bed): Kernel trap at 0x00199bf0, type 14=page fault, registers:
<<<16 registers of hex>>>
Error code: 0x00000000

Debugger called:<panic>
Backtrace, Format - Frame : Return Address (4 potential args on stack)
16 lines of {censored}
Backtrace terminated-invalid frame pointer 0
BSD process name corresponding to current thread: kernel_task

Mac OS version;
9B18

Kernel version:
Darwin Kernel Version 9.1.0: Sun Jan 27 14:40:01 PST 2008; root:xnu-1228.obj/RELEASE_I386

 

is there anything that you can add to this?

 

 

 

PS

 

 

I confirmed that having IDE hard drives when there is more than 2GB of system memory definitely causes kernel panics. With no IDE hard drives, there are no panics. It has been proposed that AppleVIAATA.kext is causing the panics, but unfortunately, that source code is not available.

 

PPS:

 

More musings on AppleVIAATA.kext:

 

info.plist looks like this:

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>AppleVIAATA</string>
<key>CFBundleGetInfoString</key>
<string>1.0.2, Copyright Apple Computer, Inc. 2004</string>
<key>CFBundleIdentifier</key>
<string>com.apple.driver.AppleVIAATA</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Apple VIA ATA Driver</string>
<key>CFBundlePackageType</key>
<string>KEXT</string>
<key>CFBundleShortVersionString</key>
<string>1.0.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0.2</string>
<key>IOKitPersonalities</key>
<dict>
	<key>VIA ATA Driver</key>
	<dict>
		<key>CFBundleIdentifier</key>
		<string>com.apple.driver.AppleVIAATA</string>
		<key>IOClass</key>
		<string>AppleVIAATADriver</string>
		<key>IOProviderClass</key>
		<string>AppleVIAATAChannel</string>
	</dict>
	<key>VIA PATA Controller</key>
	<dict>
		<key>CFBundleIdentifier</key>
		<string>com.apple.driver.AppleVIAATA</string>
		<key>Hardware Name</key>
		<string>82C571</string>
		<key>IOClass</key>
		<string>AppleVIAATARoot</string>
		<key>IOPCIPrimaryMatch</key>
		<string>0x05711106</string>
		<key>IOProbeScore</key>
		<integer>1000</integer>
		<key>IOProviderClass</key>
		<string>IOPCIDevice</string>
		<key>ISA Bridge Matching</key>
		<dict>
			<key>IOPCIClassMatch</key>
			<string>0x06010000&0xffff0000</string>
			<key>IOProviderClass</key>
			<string>IOPCIDevice</string>
		</dict>
		<key>Serial ATA</key>
		<false/>
	</dict>
	<key>VIA SATA Controller</key>
	<dict>
		<key>CFBundleIdentifier</key>
		<string>com.apple.driver.AppleVIAATA</string>
		<key>Hardware Name</key>
		<string>8237 SATA</string>
		<key>IOClass</key>
		<string>AppleVIAATARoot</string>
		<key>IOPCIPrimaryMatch</key>
		<string>0x2363197B 0x31491106 0x00e310de 0x005410de 0x005510de</string>
		<key>IOProbeScore</key>
		<string>1000</string>
		<key>IOProviderClass</key>
		<string>IOPCIDevice</string>
		<key>Serial ATA</key>
		<true/>
	</dict>
</dict>
<key>OSBundleLibraries</key>
<dict>
	<key>com.apple.iokit.IOATAFamily</key>
	<string>1.5.0d1</string>
	<key>com.apple.iokit.IOPCIFamily</key>
	<string>1.1</string>
	<key>com.apple.kernel.iokit</key>
	<string>1.1</string>
</dict>
<key>OSBundleRequired</key>
<string>Local-Root</string>
</dict>
</plist>

 

My IDE hard drives appear as Serial-ATA in System Profiler, whereas my SATA drives appear under Generic AHCI. So, maybe the VIA SATA controller is what deals with IDE hard drives, or it is VIA ATA. I tend to think it is VIA SATA, since that is what appears in system profiler. Is there anything wrong there?

 

PPPS:

 

After looking at my mobo manual, it appears that the IDE slot (ATA-133/100/66/33 IDE Channel) is connected to the "Gigabyte SATA2" controller. So that would explain why it appears as a Serial- ATA device.

Link to comment
Share on other sites

I'll take a look at the code.

 

My motherboard supports only IDE mode (no AHCI). All my SATA devices show up under Serial-ATA. I have no EIDE devices. So far I am not sure what's causing panics. In the other thread someone suggested disabling memory remap in my BIOS; So far it helped, I am unable to crash. So maybe it's not IDE mode / IDE drives afterall; I am also not using jMicron (it's disabled in the BIOS).

 

If I manage to pull a GSOD with my current system, 'll let you know.

Link to comment
Share on other sites

I'll take a look at the code.

 

My motherboard supports only IDE mode (no AHCI). All my SATA devices show up under Serial-ATA. I have no EIDE devices. So far I am not sure what's causing panics. In the other thread someone suggested disabling memory remap in my BIOS; So far it helped, I am unable to crash. So maybe it's not IDE mode / IDE drives afterall; I am also not using jMicron (it's disabled in the BIOS).

 

If I manage to pull a GSOD with my current system, 'll let you know.

 

ok.

 

How much RAM do you have, and on what mobo?

 

I don't think I can disable memory remap, or I would.

Link to comment
Share on other sites

ok.

 

How much RAM do you have, and on what mobo?

 

I don't think I can disable memory remap, or I would.

 

Yeah, there's no such option on Gigabyte boards; I can't find such setting on my DS3R board.

I have 4gb OCZ DDR800, Vanilla P5K board.

 

I think it's really the memory remap that's {censored} us. I disabled it in the morning, and been running extensive tests all day - absolutely 0 GSODs.

 

I bought DS3R to replace my P5K vanilla board, but it looks like 'll have to return the DS3R because of lack of remap option and get a better P5K based board.

 

I am also running in IDE mode, not AHCI. So it seems that it has no affect.

Link to comment
Share on other sites

IOGeneralMemoryDescriptor"@/SourceCache/xnu/xnu-1228.0.2/iokit/Kernel/IOMemoryDescriptor.cpp:1471

 

Is this saying that the function is located in IOMemoryDescriptor.cpp, or that whatever called the function is located in IOMemoryDescriptor.cpp?

 

If it's the place where the function is called, THAT should be replaced with the 64 bit version, rather than modifying the 32bit function itself. It's only getting called in one place, since we all have basically the same kernel panics every time. I would assume that it is in AppleVIAATA, since it's the driver.

 

Am I repeating what we already know?

 

I just don't really know anything about coding on the mac platform...

Link to comment
Share on other sites

IOGeneralMemoryDescriptor"@/SourceCache/xnu/xnu-1228.0.2/iokit/Kernel/IOMemoryDescriptor.cpp:1471

 

Is this saying that the function is located in IOMemoryDescriptor.cpp, or that whatever called the function is located in IOMemoryDescriptor.cpp?

 

If it's the place where the function is called, THAT should be replaced with the 64 bit version, rather than modifying the 32bit function itself. It's only getting called in one place, since we all have basically the same kernel panics every time. I would assume that it is in AppleVIAATA, since it's the driver.

 

Am I repeating what we already know?

 

I just don't really know anything about coding on the mac platform...

Normally you get the line where exception has occured. It could be a call to something that produced the exception (if you don't have access to that piece of code); or it could be a piece of code that, indeed, caused the exception.

 

I haven't had a chance to look at that yet; I'll do it today.

 

PS. Alright, which kernel source do I get and where?

PS2. You see this?

http://lists.apple.com/archives/darwin-dri...t/msg00006.html

http://forum.insanelymac.com/index.php?sho...st&p=384876

Link to comment
Share on other sites

Asus P5K-E WiFi-AP: After disabled "memory remap" I have not GSODs at all! Even with Aperture + Lightroom + Photoshop at the same time.

My OSX placed at PATA HDD (jMicron), I have 4Gb of memory (3,2 after "memory remap - off").

Link to comment
Share on other sites

I think I might have seen the beginning of that thread... but it is very interesting! In it, I believe they mentioned a way to get around this... but I don't have the code to try it out.

 

This entry from it: http://lists.apple.com/archives/darwin-dri...t/msg00013.html

 

It says we should be using IODMACommand... is that a library of sorts? Where?

 

Also, I downloaded the apple example pci driver... if anyone wants it... I assume it's against the rules to post it here.

Link to comment
Share on other sites

Kirby, a quick question. Which method did you use to patch 10.5.2 and 9.2? I can't seem to get it working on my DS3R (I swapped motherboards today), keep getting GSODs at boot. Actually no, I can boot with -x.

 

This entry from it: http://lists.apple.com/archives/darwin-dri...t/msg00013.htmlIt says we should be using IODMACommand... is that a library of sorts? Where? Also, I downloaded the apple example pci driver... if anyone wants it... I assume it's against the rules to post it here.
Yeah we'll need to do quite a bit of learning with this.

XCode documentation -> Code refence library -> Hardware & drivers -> ATA -> Kernel framework reference,

then search for IODMACommand.

 

This is description:

The IODMACommand is supersedes the IOMemoryCursor and greatly enhances the functionality and power of it. The command can be specified to output 64-bit physical addresses and also allows driver writers to bypass mapping hardware or get addresses suitable for non-snooped DMA.

 

IODMAcommand is designed to be very easily subclassable. Most driver writers need to associate some DMA operations with their memory descriptor and usually use a C structure for that purpose. This structure is often kept in a linked list. The IODMACommand has built-in linkage and can be derived and 'public:' variables added, giving the developer a structure that can associate a memory descriptor with a particular DMA command but will also allow the developer to generate that command and keep the state necessary for tracking it.

 

It is envisaged that a pool of IODMACommands will be created at driver initialization and that each command will be kept in an IOCommandPool while not in use. However, if developers wish to maintain their own free lists that is certainly possible. See the and for more information on manipulating the command's doubly linked list entries.

 

The IODMACommand can be used in a 'weak-linked' manner. To do this you must avoid using any static member functions. Use the much slower but safe weakWithSpecification function. On success a DMA command instance will be returned. This instance can then be used to clone as many commands as is needed. Remember deriving from this class cannot be done weakly, in other words, no weak subclassing!

Link to comment
Share on other sites

Yes, that seems... daunting. there is so much to learn just to understand the definition!

 

I program, but I've never done any hardware stuff.

 

as far as 10.5.2: http://forum.insanelymac.com/index.php?showtopic=87078

I followed those directions exactly. The only kexts I reinstalled were SMBios and my audio (alcinject and applehda). The only problem I had was that at first boot after the upgrade, it just sat at the gray screen (I forgot to go verbose)... so I hard reset it. It booted straight away! I didn't even have to reinstall natit.

Link to comment
Share on other sites

Normally you get the line where exception has occured. It could be a call to something that produced the exception (if you don't have access to that piece of code); or it could be a piece of code that, indeed, caused the exception.

 

I haven't had a chance to look at that yet; I'll do it today.

 

PS. Alright, which kernel source do I get and where?

PS2. You see this?

http://lists.apple.com/archives/darwin-dri...t/msg00006.html

http://forum.insanelymac.com/index.php?sho...st&p=384876

 

the source code for AppleVIAATA.kext has not been released. which really sucks.

 

Since the problem is probably in there, and we can't get that source code, we have to find another way to fix it. I think the only way seems to be that section of code in IOMemoryDescriptor.

 

so something is calling "getPhysicalSegment" with an address out of 32 bit range. this brings up a question: is it just out of 32 bit range, or is it out of 64 bit range too?

 

when i modified the code to call the getPhysicalSegment64, it began to return addresses in the 64 bit range. When getPhysicalSegment returns a value, it returns it ass addr_64t. this can obviously handle 64 bit addresses. you then type cast (covert from one data type to another) it into IOPhysicalAddress. However, it is possible that IOPhysicalAddress cannot handle 64 bit addresses, and that converting a 64 bit address into IOPhysicalAddress causes the page fault kernel panic.

 

But the problem is that whatever is calling "getPhysicalSegment" needs a 64 bit address returned, but also wants it in the form of IOPhyiscalAddress. If this is impossible, then the only possible fix is using the AppleVIAATA.kext source code. which we don't have.

 

:/

 

is it possible that it the bug is in a different kext? one we have source code for?

 

EDIT:

 

more looking, and C++ stuff:

 

getPhysicalSegment is a public function within the IOMemoryMap, which is used with the IO kit (writing device drivers) as opposed to normal kernel stuff. which fits with the IDE thing.

 

there are two "getPhysicalSegment64" functions, one immediately above and one immediately below getPhysicalSegment in the source code. the bottom getPhysicalsegment64 calls getPhysicalSegment.

 

hmm

Link to comment
Share on other sites

  • 2 weeks later...

ok so i did some more searching. The most up-to-date source code i could find for AppleVIAATA.kext was 10.4.3. I downloaded this, and built it using XCode 3.0 on my hackintosh. I took this and started using it, and after a couple reboots everything was working absolutely normally. So this is definitely the code we need to fix.

 

it can be found here: http://www.opensource.apple.com/darwinsource/10.4.3/

 

I searched the source code (after opening the project in XCode), and found the problem command in one place.

 

while ( _DMACursor->getPhysicalSegments(
					   /* descriptor */ descriptor,
					   /* position   */ xfrPosition,
					   /* segments   */ &physSegment,
					   /* max segs   */ 1,
					   /* max xfer   */ bytesRemaining,
					   /* xfer size  */ &transferSize) )
{

so that is the part that we need to fix. The getPhysicalSegments function is in IOMemoryCursor.h (in the source files of the leopard kernel), and it is simply a wrapper for "genPhysicalSegments". so when getPhysicalSegments is called, genPhysicalSegments gets called. genPhysicalSegments is found in IOMemoryCursor.cpp.

 

Here is what genPhysicalSegments() looks like:

 

UInt32 
IOMemoryCursor::genPhysicalSegments(IOMemoryDescriptor *inDescriptor,
								IOPhysicalLength	fromPosition,
								void *		inSegments,
								UInt32		inMaxSegments,
								UInt32		inMaxTransferSize,
								IOByteCount		*outTransferSize)
{
if (!inDescriptor)
	return 0;

if (!inMaxSegments)
	return 0;

if (!inMaxTransferSize)
	inMaxTransferSize = maxTransferSize;

/*
 * Iterate over the packet, translating segments where allowed
 *
 * If we finished cleanly return number of segments found
 * and update the position in the descriptor.
 */
PhysicalSegment curSeg = { 0, 0 };
UInt curSegIndex = 0;
UInt curTransferSize = 0;
IOByteCount inDescriptorLength = inDescriptor->getLength();
PhysicalSegment seg = { 0, 0 };

while ((seg.location) || (fromPosition < inDescriptorLength)) 
{
	if (!seg.location)
	{
		seg.location = inDescriptor->getPhysicalSegment(
						   fromPosition, &seg.length);
		assert(seg.location);
		assert(seg.length);
		fromPosition += seg.length;
	}
...
}

if (curSeg.location)
	(*outSeg)(curSeg, inSegments, curSegIndex++);

if (outTransferSize)
	*outTransferSize = curTransferSize;

return curSegIndex;
}

 

so basically genPhysicalSegments() is the function that calls getPhysicalSegment(), which is what panics.

 

I don't know exactly what UInt32 is, but it is the type that genPhysicalSemgents() returns, and i'm assuming that it is 32 bit. So that is a major problem. This means that we can't simply call getPhysicalSegment64() instead. What we must do, according to what i have read, is rewrite this code using IODMACommand:

 

Overview

 

A mechanism to convert memory references to I/O bus addresses.

 

 

The IODMACommand is supersedes the IOMemoryCursor and greatly enhances the functionality and power of it. The command can be specified to output 64-bit physical addresses and also allows driver writers to bypass mapping hardware or get addresses suitable for non-snooped DMA.

Link to comment
Share on other sites

Sorry to interrupt the geniuses in work (good job BTW) but I did a fresh Kalyway 10.5.1 install updated to 10.5.2 with netkas 9.2.0 kernel and mac.nub smbios and no kernel panics ever. You may want to look into that...

Link to comment
Share on other sites

Sorry to interrupt the geniuses in work (good job BTW) but I did a fresh Kalyway 10.5.1 install updated to 10.5.2 with netkas 9.2.0 kernel and mac.nub smbios and no kernel panics ever. You may want to look into that...

 

that is because you have no IDE devices. If I unplug mine (or delete AppleVIAATA, which does the same thing in effect), then the kernel panics go away. I verified this a few posts back (or maybe in another thread).

 

but thank you!

 

 

EDIT::

 

I'm reading I/O Kit Fundementals, by Apple. It, along with the AppleVIAATA source code, makes the learning process similar to drinking from a fire hose.

 

but i progress.. (not digress :D )

Link to comment
Share on other sites

ok i took some notes on IOKitFundementals, and here they are:

 

DMA driver uses memory-cursor object to get memory descriptors buffer segments, and generate scatter/gather list suitable for use with the hardware. It does this by invoking getPhysicalSegments (of the memory cursor), and doing any necessary processing. Once the transfer is done, the driver invokes the memory descriptors complete function to unwire memory, and update VM state.

 

(page 88)

 

 

the IODMACommand supersedes the IOMemoryCursor class: it provides all the functionality of IOMemoryCursor and adds a way for you to specify your hardware's addressing capability and functions to copy memory to a bounce buffer when necessary. When you instantiate an IODMACommand object, you can specify the following attributes:

-number of address bits (32, 40, 64)

-max segment size

-any alignment restrictions required by your hardware

-the maximum I/O transfer size

(page 93)

 

Typical case of IODMACommand:

1) Create an IODMACommand object per I/O transaction (you can create a pool of IODMACommand objects when your driver starts)

 

2)When an I/O request arrives, use IODMACommand::setMemoryDescriptor to target the IOMemoryDescriptor object representing the request

 

3)Call IODMACommand::prepare (among other things, this function allocates the mapping resources that may be required for the transfer)

 

4) use IODMACommand functions to generate the appropriate physical addresses and lengths (IODMACommand::gen64IOVMSegments returns 64-bit addresses and lengths and IODMACommand::gen32IOVMSegments returns 32 bit addresses and lengths).

 

5) Start the hardware I/O

 

6) When the I/O is finished, call IODMACommand::complete (to complete the processing of DMA mappings), followed by IODMACommand::clearMemoryDescriptor (to copy data from the bounce buffer, if necessary, and release resources)

 

NOTE: The IODMACommand prepare and complete functions are distinct form hte IOMemoryDescriptor prepare and complete functions. The IODMACommand prepare and complete functions bracket the start and end of the DMA transaction, whereas the IOMemoryDescriptor prepare and complete functions wire and unwire the memory, and must be called as usual.

 

(page 93 to 94)

 

I'll post the modified code in a moment, whether it builds or not..

 

edit::

 

ok more info. when you are calling a function of an object, and you have the pointer of the object, use "->" not ".". so like

 

laIODMACommand->setMemoryDescriptor(descriptor);

instead of

laIODMACommand.setMemoryDescriptor(descriptor);

 

 

and i know alot of this might not make much sense, but i have been doing other reading taht i haven't mentioned here. You can use google to gain a working understanding of what i'm talking about. trust me, cause 24 hours ago i had no idea what any of this meant. :D

Link to comment
Share on other sites

I would also discount ~pcwiz's results in relation to this issue, as he isn't using a vanilla kernel. I don't know if that really matters at all in terms of this driver, but it might. is anyone else who has this issue using a non-vanilla cursor?

 

social: holy f@&$ing s$&@! great job! have the changes you made compiled yet?

Link to comment
Share on other sites

I would also discount ~pcwiz's results in relation to this issue, as he isn't using a vanilla kernel. I don't know if that really matters at all in terms of this driver, but it might. is anyone else who has this issue using a non-vanilla cursor?

 

social: holy f@&$ing s$&@! great job! have the changes you made compiled yet?

 

lol thank you ;)

 

It did compile, and i thought i had fixed everything. But when i booted with the newly compiled kext, my IDE drives didn't appear. i need to go through the code more carefully and actually understand everything that is happening. I was rushed at the end so I very well may have missed something. Its probably obvious.

 

But i confirmed that the vanilla compiled AppleVIAATA does work (though it crashes just like the normal one at high RAM).

 

Since i'm not at my hackintosh i can't post the code. I should have earlier. But i will as soon as i can.

 

Unfortunately i'm leaving town so it may be 1.5 weeks till i can work on it again. :/

 

But i will never forget! I want my last GB lol.

Link to comment
Share on other sites

here is the modified AppleVIAATADriver.cpp file in AppleVIAATA (version 1.0.2, from 10.4.3 source code)

 

IOReturn AppleVIAATADriver::createChannelCommands( void )
{
   IOMemoryDescriptor* descriptor = _currentCommand->getBuffer();
//    IOMemoryCursor::PhysicalSegment physSegment;

IOLog("LEWIS LEWIS LEWIS:: AppleVIAATA has started, and is trying the modified code");


   UInt32 index = 0;
   UInt8  *xferDataPtr, *ptr2EndData, *next64KBlock, *starting64KBlock;
   UInt32 xferCount, count2Next64KBlock;

   if ( !descriptor )
   {
       return -1;
   }

   // This form of DMA engine can only do 1 pass.
   // It cannot execute multiple chains.

   IOByteCount bytesRemaining = _currentCommand->getByteCount() ;
   IOByteCount xfrPosition    = _currentCommand->getPosition() ;
//    IOByteCount  transferSize  = 0; 

   // There's a unique problem with pci-style controllers, in that each
   // dma transaction is not allowed to cross a 64K boundary. This leaves
   // us with the yucky task of picking apart any descriptor segments that
   // cross such a boundary ourselves.  

//LEWIS: begin modified code

IODMACommand* laIODMACommand;

laIODMACommand = laIODMACommand->withSpecification(
								IODMACommand::OutputHost64,
								(UInt8) 0,
								(UInt64) 0 );


laIODMACommand->setMemoryDescriptor(descriptor);
laIODMACommand->prepare( (UInt64)0,
						(UInt64)descriptor->getLength() );
IODMACommand::Segment64 theSegment;						

UInt64 *offset = 0;
UInt32 *numSegments = (UInt32 *) 1;



IOLog("attempting to gen64IOVMSegments");


while ( laIODMACommand->gen64IOVMSegments(
			/* offset   */	(UInt64 *)offset,
			/* segments */	&theSegment,
			/* max segs */	(UInt32 *)numSegments ) )
   {
       xferDataPtr = (UInt8 *) theSegment.fIOVMAddr;
       xferCount   = theSegment.fLength;

       if ( (UInt32) xferDataPtr & 0x01 )
       {
           IOLog("%s: DMA buffer %p not 2 byte aligned\n",
                 getName(), xferDataPtr);
           return kIOReturnNotAligned;        
       }

       if ( xferCount & 0x01 )
       {
           IOLog("%s: DMA buffer length %ld is odd\n",
                 getName(), xferCount);
       }

       // Update bytes remaining count after this pass.
       bytesRemaining -= xferCount;
       xfrPosition += xferCount;

       // Examine the segment to see whether it crosses (a) 64k boundary(s)
       starting64KBlock = (UInt8*) ( (UInt32) xferDataPtr & 0xffff0000);
       ptr2EndData  = xferDataPtr + xferCount;
       next64KBlock = starting64KBlock + 0x10000;

       // Loop until this physical segment is fully accounted for.
       // It is possible to have a memory descriptor which crosses more
       // than one 64K boundary in a single span.

       while ( xferCount > 0 )
       {
           if (ptr2EndData > next64KBlock)
           {
               count2Next64KBlock = next64KBlock - xferDataPtr;
               if ( index < kATAMaxDMADesc )
               {
                   setPRD( xferDataPtr, (UInt16)count2Next64KBlock,
                           &_prdTable[index], kContinue_PRD);

                   xferDataPtr = next64KBlock;
                   next64KBlock += 0x10000;
                   xferCount -= count2Next64KBlock;
                   index++;
               }
               else
               {
                   IOLog("%s: PRD table exhausted error 1\n", getName());
                   _dmaState = kATADMAError;
                   return -1;
               }
           }
           else
           {
               if (index < kATAMaxDMADesc)
               {
                   setPRD( xferDataPtr, (UInt16) xferCount,
                           &_prdTable[index],
                           (bytesRemaining == 0) ? kLast_PRD : kContinue_PRD);
                   xferCount = 0;
                   index++;
               }
               else
               {
                   IOLog("%s: PRD table exhausted error 2\n", getName());
                   _dmaState = kATADMAError;
                   return -1;
               }
           }
       }
   } // end of segment counting loop.

   if (index == 0)
   {
       IOLog("%s: rejected command with zero PRD count (0x%lx bytes)\n",
             getName(), _currentCommand->getByteCount());
       return kATADeviceError;
   }

   // Transfer is satisfied and only need to check status on interrupt.
   _dmaState = kATADMAStatus;

   // Chain is now ready for execution.
   return kATANoErr;
}

 

but alas, my IDE devices are not detected at all with this new code :/

 

so must try more later.

Link to comment
Share on other sites

  • 6 months later...
  • 3 months later...

im a newbie i have a hackintosh running mac quad intel osx 10.5.2 with 4 gigs ram,I accidentally did an update software on the osx and I cant boot the computer anymore. I have a panic debugger...is there a fix for this? Please be easy on me im not very versed in code. Please help

Link to comment
Share on other sites

 Share

×
×
  • Create New...