There are general pointers programming hardware devices:
1. You spin for 0xffff times then you use delay function in 1ms increments or less then you setup a timer and quit you process. Delay function is like spin (it blocks) but at least you know exact time.
2. PHY terminology is used in many devices. Its lowest possible thing that must be verified first.
3. If you got initial functionality working on emulator then test it on real hardware before going futher.
Ata ahci related
0. Uefi based motherboard dont generally have bios handoff in bios mode.
0. Make sure bits 0,4,14,15 =0 inside PxCMD for all implemented ports.
1. You do hba reset - it’ll be lightning fast on real hardware if you did prev step. Disable main and port interrupts. Make sure PxCMD BITS 2,1=1 and make sure PxSCTL =0 for all implemented ports.
2. Setup PxFB with valid phys addr. PxCLB is optional, I like 0 in there.
3. Your third loop thru implemented ports: write 0x701 into PxSCTL. The 7 disables power management - you dont need this without super clear understanding how ahci works.
4. Wait 2 ms. You must know its 2ms. Its not 0xffff loops.
5. 4th loop thru implemented ports: clear PxSERR by writing -1, and enable all per port interrupts.
6. Enable global intertupts - GHE = 0x80000002
7. please stop any futher loop spinning - its slower and less predictable
8. 5th loop thru implemented ports: write 0x700 into PxSCTL
9. quit you main process and wait for interrupt.
A) PxFB is Receive FISes. Used when device wants to send you very small data like status or setting. On most motherboards (but not all) this mem content can be 0 for device to send you data
Interrupt:
1) Inside interrupt you check if triggered port is your already established port. If not you proceed to messy very messy initialization - you need to reach 0x1_3 in PxSSTS. Its all inside single interrupt if BSY doesnt timeout and PxSSTS doesnt drop to 0x0_0
2) For established ports: on every irq you check that value of PxSSTS=0x1_3
3) then you check that 24+ bits inside PxIS are not set, if set you need to set PxCMD bits 0,15 to 0 and then back to 1. If during this process BSY remains 0 then you can continue even if prev command set error bit in PxTFD. Its insde 6.2 chapter of ahci 1.3.1 docs.
4) then you can check original PxTFD to see if prev command returned error
A) 2byte PxTFD is copy of certain bytes of a Receive FIS
B) forget about FRE and FR - they will always remain set.
AHCI initialization sequence for real hardware
Re: AHCI initialization sequence for real hardware
Overall docs say that writing 1 to where is already 1 is not supportedBonfra wrote:2) the bit in PxCI is never cleared as if the command has been rejected,.
You need to examine errors in PxIS - some of them terminate any futher host issuing commands to device unless you clear bits 0,15 of PxCMD first (PxCI gets cleared) and then set both to 1. If BSY in PxTFD wasnt set during this process then you can run another command.
Delays do not fix anything. Clear understanding how device states change do.
Re: AHCI initialization sequence for real hardware
I'm sorry I didn't quite understand which part of the code you are referring to, can you link the specific parts?
Like
One last thing I'd like not to use interrupts, maybe in a later iteration. for now, I'd like to keep the flow linear.
Like
where.Crono wrote: 4. Wait 2 ms.
One last thing I'd like not to use interrupts, maybe in a later iteration. for now, I'd like to keep the flow linear.
Regards, Bonfra.
Re: AHCI initialization sequence for real hardware
The docs say min 1ms, but you dont understand that max is not set.
Another thing you probably dont understand that getting PxSSTS = 0x1_3 is priority during device detection. Its practically key of getting correct signature.
Another thing you probably dont understand that getting PxSSTS = 0x1_3 is priority during device detection. Its practically key of getting correct signature.
Re: AHCI initialization sequence for real hardware
So I tried following your list even if I didn't understand what point referred to what part, meanwhile trying to adapt it to a no-interrupt approach. This time I basically followed 1:1 the specs without making any assumptions, and I think it is pretty accurate.
I'm keeping the repo updated with the latest working code.
The problem still persists: device reset/int works, command sending works, but I cannot straight up send commands after init, I must wait some time. I’m trying to understand better and fix this behavior
I'm keeping the repo updated with the latest working code.
The problem still persists: device reset/int works, command sending works, but I cannot straight up send commands after init, I must wait some time. I’m trying to understand better and fix this behavior
Regards, Bonfra.
Re: AHCI initialization sequence for real hardware
Well, it's kina embarrassing to admit, but it was all working with the new version of the code. What I did wrong that made the first command fail was that I didn't zeroed out the command structure, it contained some stack garbage... anyway, now it works without any delay.
Thanks a lot for helping me during this journey
Thanks a lot for helping me during this journey
Regards, Bonfra.