flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > Re-Start... |
Author |
|
smiddy 21 Sep 2014, 14:55
Hi All,
It has been a long time since I delved into playing with my OS: http://board.flatassembler.net/topic.php?t=5911 Recently I've made a lot of learning progress on my approach, which had been through a method of going form protected mode back to real mode in order to use BIOS interrupts, but alas, since 64 bit machines are more prevalent now, I figured it was time to work out the use of i/o ports to do the things I wish within my OS. In getting to this point I have worked out PCI enumeration and can get to my mass storage controller (listed as an IDE controller, but really is a SATA controller). Reading the BARs I get these I/O ports: Code: BAR0=0000DC01 BAR1=0000D881 BAR2=0000D801 BAR3=0000D481 BAR4=0000D401 These are not all of the I/O ports associated with my controller, as a comparison, using Windows System Information I/O there are a total of 16 I/O ports list, the five above are a part of that listing. In reading a ton of SATA, AHCI, and IDE materials I am not finding a mechanism to find those other ports (ala the other ports do contain two HDDs and a BD). For now I have hard coded the ports in and I can interface with the drives, ID them, etcetera, but would like to know a mechanism to retrieving the rest of the I/O ports. Can anyone point me to where I might find this information? My current list of references: http://wiki.osdev.org/ATA_PIO_Mode http://wiki.osdev.org/PCI_IDE_Controller https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0CB4QFjAA&url=http%3A%2F%2Fwww.knowledgetek.com%2FgraphicsNew%2FSerialATA_Revision_3_2_Gold(with%2520Links).pdf&ei=teUeVK3TNdSfyATDuoGgDg&usg=AFQjCNH3729CdfXFzM4spoIYeJBfF25dHA&sig2=cE2L2B1_3HvkYrWJCzdm_g&bvm=bv.75775273,d.b2U 82801eb-82801er-serial-ata-manual.pdf serial-ata-ahci-spec-rev1-3-1.pdf I have also search within OS Construction and the returned items do not cover what to do if your controller has more than 5 I/O ports (BTW, according to one document BAR4 is supposed to be bus mastering, whatever that means, perhaps that is the BAR I need to manipulate to derive the rest of the ports?). Thanks in advance for any ideas, assistance, Smiddy |
|||
21 Sep 2014, 14:55 |
|
smiddy 21 Sep 2014, 16:19
Thanks!
I think I may have stumbled onto it, but it is NOT clear. My controller is defined as 01h class code 01h subclass, which is NOT AHCI (01h and 06h respectively). However, in BAR5 there is an address which I believe contain the HBA memory registers, with the Port 0 offset at 100h. I will review that memory locale shortly. If at each 100h locale are the I/O port, I think I figured it out. To answer your points: 1) yeah, only one shows up (if configured in BIOS), 01h class and 01h subclass even when forcing AHCI. 2) Yep, I can access the masters (no slave installed, but have IDE code to ID them if they were) 3) See 1) above. LOL! I find it pretty confusing because it isn't very clear cut. Smiddy |
|||
21 Sep 2014, 16:19 |
|
smiddy 21 Sep 2014, 17:00
I played with my BIOS some and it seems that the actual controller my HDDs and BD are on is hidden from PCI enumeration. No 01h Class present. In this case what do you do? Man this is frustrating...
Windows 7 64 bit sees them fine, but I suspect maybe it is using ACPI to determine if installed. I was hoping to avoid that. |
|||
21 Sep 2014, 17:00 |
|
BAiC 21 Sep 2014, 17:51
I've never seen this situation with IDE drives. I have, however, seen it with Floppy controllers and the PnP enumeration technique. perhaps your enumerator isn't accounting for the type of controller that is present. have you written a "dumping" routine that prints all of the controllers available?
- Stefan _________________ byte me. |
|||
21 Sep 2014, 17:51 |
|
smiddy 21 Sep 2014, 20:09
Yep, that is essentially what I've done first, hit ever bus...get the installed devices. There are no mass storage devices present (01h Class). If I hard code the ports though I can interface with them.
|
|||
21 Sep 2014, 20:09 |
|
smiddy 21 Sep 2014, 20:12
Code: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PCI.ASM - Devloped to test things: ;; ;; To Assemble: fasm pci.asm ;; ;; 1.00.0 - Initial release. Going to work on PCI devices ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; format MZ ; For FASM EXE format entry main:BeginPCI ; Entry is into the main segment, just below segment main use16 BeginPCI: jmp Start ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Program data items ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ProgramMessage db 13,10,'PCI - 1.00.0 Testing PCI Stuff... -smiddy',13,10,13,10,0 RebootMessage db 13,10,'Press any key to reboot...',13,10,0 TheEndOfLine db 13,10,0 TheSpace db ' ',0 ThePort db 'Port: ',0 TypeHeaderMessage db 'Type X Header',0 NumberToConvert dd 1,2,3 ; 96-bit Number ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; This is the start of the pragram ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Start: mov ax,9000h ; Set up stack mov ss,ax mov sp,9500h ; Stack pointer setup mov ax,cs ; Setup the rest of the segment registers mov ds,ax mov es,ax mov fs,ax mov gs,ax mov [CodeSegment],ax ; Save current codesegment for decisions later mov si,ProgramMessage ; Load program message call PrintString ; Display welcome message call PCIDump ; Calls the testing function to run cmp [CodeSegment],0202h ; Compare for booted executeable je .Reboot ; Yes, go to reboot routine mov ax,4C00h ; Terminate program if in DOS int 21h ; DOS interrupt call .Reboot: mov si,RebootMessage ; Load reboot message into SI call PrintString mov ax,0 ; Load INT 16h get key function int 16h ; BIOS interrupt call db 0EAh ; Machine language to jump to ; address FFFF:0000 (reboot) dw 0 dw 0FFFFh ; No return required ; we're rebooting! ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; PCIDump - Dump all Device and Vendor ID's to the screen ;; ;; IN: Nothing ;; OUT: Nothing, All registers preserved ;; http://pci-ids.ucw.cz/read/PC/ - Online list of Device and Vendor ID's ;; ;; Configuration Mechanism One has two IO port rages associated with it. ;; The address port (0xcf8-0xcfb) and the data port (0xcfc-0xcff). ;; A configuration cycle consists of writing to the address port to specify which device and register you want to access and then reading or writing the data to the data port. PCI_CONFIG_ADDRESS EQU 0x0CF8 PCI_CONFIG_DATA EQU 0x0CFC ;; address dd 10000000000000000000000000000000b ;; /\ /\ /\ /\ /\ /\ ;; E Res Bus Dev F Reg 0 ;; Bits ;; 31 Enable bit = set to 1 ;; 30 - 24 Reserved = set to 0 ;; 23 - 16 Bus number = 256 options ;; 15 - 11 Device/Slot number = 32 options ;; 10 - 8 Function number = will leave at 0 (8 options) ;; 7 - 2 Register number = will leave at 0 (64 options) 64 x 4 bytes = 256 bytes worth of accessible registers ;; 1 - 0 Set to 0 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PCIDump: push edx push ecx push ebx push eax xor ecx, ecx xor eax, eax mov ecx, 0x80000000 ; Bit 31 must be set .CheckNext: mov byte [NumberOfRegisters],0 mov eax, ecx mov dx, PCI_CONFIG_ADDRESS out dx, eax mov dx, PCI_CONFIG_DATA in eax, dx ; EAX now holds the Device and Vendor ID cmp eax, 0xffffffff ; 0xFFFFFFFF means no device present on that Bus and Slot je .NothingThere push ecx ; Save counter ECX push eax ; Save EAX for second use mov eax,ecx ; Put counter into ToHex for displaying mov cl,32 call ToHex mov si,HexBuffer call PrintString mov si,TheSpace call PrintString pop eax ; Restore resulting EAX, show Device ID and Vendor ID mov cl,32 call ToHex mov si,HexBuffer call PrintString mov si,TheSpace call PrintString pop ecx push ecx mov eax,ecx mov al,08h ; Get register 8's data mov dx, PCI_CONFIG_ADDRESS out dx, eax mov dx, PCI_CONFIG_DATA in eax,dx mov cl,32 call ToHex mov si,HexBuffer call PrintString mov si,TheSpace call PrintString pop ecx push ecx mov eax,ecx mov al,0Ch ; Lets see what type of header we have from register C mov dx, PCI_CONFIG_ADDRESS out dx, eax mov dx, PCI_CONFIG_DATA in eax,dx and eax,0FF0000h ; Just want to check bits 23 - 16 shr eax,16 cmp al,2 je .Type02 cmp al,1 je .Type01 jmp .Type00 .Type02: mov byte [TypeHeaderMessage+5],'2' mov si,TypeHeaderMessage call PrintString mov si,TheEndOfLine call PrintString pop ecx jmp .NothingThere .Type01: mov byte [TypeHeaderMessage+5],'1' mov si,TypeHeaderMessage call PrintString mov si,TheEndOfLine call PrintString pop ecx jmp .NothingThere .Type00: pop ecx push ecx mov eax,ecx mov al,10h ; Register 10h mov dx, PCI_CONFIG_ADDRESS out dx, eax mov dx, PCI_CONFIG_DATA in eax,dx cmp eax,0 je .Type00p2 mov cl,32 call ToHex mov si,HexBuffer call PrintString mov si,TheSpace call PrintString inc byte [NumberOfRegisters] .Type00p2: pop ecx push ecx mov eax,ecx mov al,14h ; Register 14h mov dx, PCI_CONFIG_ADDRESS out dx, eax mov dx, PCI_CONFIG_DATA in eax,dx cmp eax,0 je .Type00p3 mov cl,32 call ToHex mov si,HexBuffer call PrintString mov si,TheSpace call PrintString inc byte [NumberOfRegisters] .Type00p3: pop ecx push ecx mov eax,ecx mov al,18h ; Register 18h mov dx, PCI_CONFIG_ADDRESS out dx, eax mov dx, PCI_CONFIG_DATA in eax,dx cmp eax,0 je .Type00p4 mov cl,32 call ToHex mov si,HexBuffer call PrintString mov si,TheSpace call PrintString inc byte [NumberOfRegisters] .Type00p4: pop ecx push ecx mov eax,ecx mov al,1Ch ; Register 1Ch mov dx, PCI_CONFIG_ADDRESS out dx, eax mov dx, PCI_CONFIG_DATA in eax,dx cmp eax,0 je .Type00p5 mov cl,32 call ToHex mov si,HexBuffer call PrintString mov si,TheSpace call PrintString inc byte [NumberOfRegisters] .Type00p5: pop ecx push ecx mov eax,ecx mov al,20h ; Register 20h mov dx, PCI_CONFIG_ADDRESS out dx, eax mov dx, PCI_CONFIG_DATA in eax,dx cmp eax,0 je .Type00p6 mov cl,32 call ToHex mov si,HexBuffer call PrintString mov si,TheSpace call PrintString inc byte [NumberOfRegisters] .Type00p6: pop ecx push ecx mov eax,ecx mov al,24h ; Register 24h mov dx, PCI_CONFIG_ADDRESS out dx, eax mov dx, PCI_CONFIG_DATA in eax,dx cmp eax,0 je .Type00pFinishLine mov cl,32 call ToHex mov si,HexBuffer call PrintString cmp byte[NumberOfRegisters],5 je .Type00p7 .Type00pFinishLine: mov si,TheEndOfLine call PrintString .Type00p7: pop ecx ; Repopulate ECX counter .NothingThere: add ecx, 0x800 cmp ecx, 0x81000000 ; The end has been reached (already looked at 8192 devices) jne .CheckNext .DumpDevicesEnd: pop eax pop ebx pop ecx pop edx ret ; ----------------------------------------------------------------------------- ; os_pci_read_reg -- Read a register from a PCI device ; IN: BL = Bus number ; CL = Device/Slot/Function number ; DL = Register number ; OUT: EAX = Register information ; All other registers preserved PCIReadReg: push edx push ecx push ebx shl ebx, 16 ; Move Bus number to bits 23 - 16 shl ecx, 8 ; Move Device/Slot/Fuction number to bits 15 - 8 mov bx, cx shl edx, 2 mov bl, dl and ebx, 0x00ffffff ; Clear bits 31 - 24 or ebx, 0x80000000 ; Set bit 31 mov eax, ebx mov dx, PCI_CONFIG_ADDRESS out dx, eax mov dx, PCI_CONFIG_DATA in eax, dx pop ebx pop ecx pop edx ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Dumps DS:SI to the screen using video BIOS call or DOS call ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PrintString: pusha .DoItAgain: lodsb ; Load byte at DS:SI into AL or al,al ; Test if character is 0 ; (end of string) jz .Done ; Go to Done if Zero cmp [CodeSegment],0202h ; Did we boot this puppy? jne .DOS ; No, then do DOS routine ;;;;;;;;;;;;;;;;;;;;;;; ;; BIOS Print Character ;;;;;;;;;;;;;;;;;;;;;;; .BIOS: mov ah,0Eh ; Put character on screen at the ; currrent cursor location mov bx,7 ; Video attribute for the character int 10h ; Call BIOS jmp .DoItAgain ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; DOS Print Character (added to use pipes) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .DOS: mov dl,al ; Put character into DL mov ah,2 ; Output Character (Interrupt 21h, service 2) int 21h jmp .DoItAgain .Done: popa ret ; Return to caller ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ToHex ;; Loads HexBuffer with ASCII corresponding to 8, 16, or 32 bit interger in hex. ;; Requires interger in AL, AX, or EAX depending on bit size ;; Requires the number of bits in the CL ;; Returns a full buffer or an empty buffer on error ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ToHex: pusha MOV BX,0 ; Load BX with pointer offset MOV edx,EAX ; Save the EAX to EDX CMP CL,8 ; Check for 8 bits JNE .Check16 JMP .ConverterLoop ; Start loading the buffer .Check16: CMP CL,10h ; Check for 16 bits JNE .Check32 JMP .ConverterLoop ; Start loading the buffer .Check32: CMP CL,20h ; Check for 32 bits JNE .ErrorBits .ConverterLoop: MOV EAX,edx ; Reload EAX with the converter SUB CL,4 ; Lower bit count by 4 bits SHR EAX,CL AND AL,0Fh ADD AL,'0' CMP AL,'9' JBE .LoadBuffer ADD AL,'A'-'0'-10 ; Convert to "A" to "F" .LoadBuffer: MOV [HexBuffer + BX],AL ; Load buffer with AL INC BX ; Increment buffer pointer CMP CL,0 ; Check if we're done JNE .ConverterLoop ; Do next byte .ErrorBits: MOV byte [HexBuffer + BX],0 ; End the string with a zero popa RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; StringLength: ;; ;; Assumes string start at ES:EDI ;; ;; Returns the string length in the ECX ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; StringLength: push edi push eax sub ecx,ecx sub al,al not ecx cld repne scasb not ecx dec ecx pop eax pop edi ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; AddCommas: ;; ;; Assumes string start at DS:ESI (currently assumes that DecimalBuffer is used) ;; ;; Populates CommasBuffer with at most three extra commas ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; NumberOfCommas dd 0 TheCommasMessage db 'The number of commas = ',0 NumberOfCharacters dd 0 TheCharactersMessage db 'The number of characters left to display = ',0 TheStringLength dd 0 StringLengthMessage db 'The string length is = ',0 AddCommas: push eax push ebx push ecx push edx mov ecx,0 mov ecx,0 ; Initialize ECX mov edi,DecimalBuffer ; Load non-comma'd buffer call StringLength ; Get the length of the string in ECX mov [TheStringLength],ecx ; Save the String's length for use later mov edx,0 ; Initialize EDX to 0, for division mov eax,ecx ; Load accumulator with length mov ebx,3 ; load up the divisor to do modula div ebx ; Divide by 3, get the integer result in EAX (number of commas), ; and remainder in EDX (number of characters before a comma) ; EAX contains the number of commas mov [NumberOfCommas],eax mov [NumberOfCharacters],edx mov ebx,0 ; EBX is use to count up the DecimalBuffer mov ecx,0 ; ECX is now use to count up the CommaBuffer cmp edx,0 ; If EDX is zero, then je .ReduceCommas ; We need to reduce the number of commas ; Otherwise we start the addition of commas process .LoopThroughCommas: dec edx ; Remove a character to add mov al,[DecimalBuffer+ebx] ; Get a character to copy to CommaBuffer mov [CommaBuffer+ecx],al ; Add to CommaBuffer inc ebx ; Next character inc ecx ; Next character cmp edx,0 je .AddComma ; If EDX = 0 then we add a comma jmp .LoopThroughCommas ; Do it again .AddComma: mov byte [CommaBuffer+ecx],',' ; Add comma inc ecx ; Next character, a comma .ReduceCommas: mov edx,3 ; Reset number of characters to move dec byte [NumberOfCommas] ; Reduce number of commas left by one jnz .LoopThroughCommas ; Not clean, then loop again .OverAlgo: mov al,[DecimalBuffer+ebx] ; Get a character to copy to CommaBuffer mov [CommaBuffer+ecx],al ; Add to CommaBuffer mov al,[DecimalBuffer+ebx+1] ; Get a character to copy to CommaBuffer mov [CommaBuffer+ecx+1],al ; Add to CommaBuffer mov al,[DecimalBuffer+ebx+2] ; Get a character to copy to CommaBuffer mov [CommaBuffer+ecx+2],al ; Add to CommaBuffer mov al,0 ; Get set to end the string in CommaBuffer mov [CommaBuffer+ecx+3],al ; Add to CommaBuffer .Done: pop edx pop ecx pop ebx pop eax ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; AddForwardSpaces: ;; ;; Assumes string start at ES:EDI, total length in EAX ;; ;; Prints forward spaces to the screen given total length in EAX ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; AddForwardSpaces: push edi push esi push eax push ecx call StringLength cmp eax,ecx jbe .Done ; If less or equal than total length, nothing to do. .MainLoop: mov si,TheSpace call PrintString inc ecx cmp eax,ecx ja .MainLoop .Done: pop ecx pop eax pop esi pop edi ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; NewToDecimal - Used to convert 96 bit DS:ESI value to decimal placing the decimal string ;; into DecimalBuffer. ;; ;; Uses 96-bit from DS:ESI as input ;; ;; Updates DecimalBuffer with ascii representation of decimal numbers. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; NewToDecimal: pusha ; Save the registers so we can restore them mov eax,[DS:ESI] ; Grab the first bits upto 32 mov [BigNumber],eax ; Load variable upto 32-bits mov eax,[DS:ESI+4] ; Grab the middle bits up to 64 mov [BigNumber+4],eax ; Load varible upto 64-bits mov eax,[DS:ESI+8] ; Grab the last bits up to 96 mov [BigNumber+8],eax ; Load variable upto 96-bits mov edx,0 ; Initialize remainder mov ebx,10 ; Divisor of 10 mov ecx,0 ; Initialize character counter .LoopBigNumber8: mov eax,[BigNumber+8] ; Load in top 32 bits div ebx ; Divide by 10 mov [BigNumber+8],eax ; Save the result, and the remainder is in the EDX .LoopBigNumber4: mov eax,[BigNumber+4] ; Load in the middle 32 bits div ebx ; Divide by 10 mov [BigNumber+4],eax ; Save the result, and the remainder is in the EDX .LoopBigNumber: mov eax,[BigNumber] ; Load in the last 32 bits div ebx ; Divide by 10 mov [BigNumber],eax ; Save the result, and the remainder is in EDX mov al,dl ; Save remainder, to be converted add al,48 ; Convert remainder number to text mov [TempBuffer+ecx],al ; Save the character into TempBuffer inc ecx mov edx,0 ; Regroup the remainder, so we can continue cmp dword [BigNumber+8],0 ; Are the top 32 bits clear? ja .LoopBigNumber8 ; Nope, keep reducing this BigNumber cmp dword [BigNumber+4],0 ; Are the middle 32 bits clear? ja .LoopBigNumber4 ; Nope, keep reducing this BigNumber cmp dword [BigNumber],0 ; Are the last 32 bits clear? ja .LoopBigNumber ; Nope, keep reducing this BirNumber mov al,0 ; The BigNumber is now clear, so load up end of string mov [TempBuffer+ecx],al ; End the string (for now) mov edi,TempBuffer ; Setup to get string length call StringLength ; Get the string length in ECX mov ebx,0 ; Setup EBX for DecimalBuffer .LoopToReverse: mov al,[TempBuffer+ecx-1] ; In reverse order (as we got here, reversely), grab a letter mov [DecimalBuffer+ebx],al ; Then place that letter in DecimalBuffer inc ebx ; Move the pointer plus one character (byte) dec ecx ; Move the point minus once character jnz .LoopToReverse ; Did we hit zero (0)? If not, loop! mov al,0 ; Load the string terminator into AL mov [DecimalBuffer+ebx],al ; Cap off the DecimalBuffer string popa ; Restore registers to where they were before entering ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Uninitiated variables ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CodeSegment rw 1 ; Saves the codesegment for decisions HexBuffer rb 18 ; Sixteen bytes with the ending zero DecimalBuffer rb 28 ; twenty six bytes with the ending zero TempBuffer rb 28 ResultBuffer rb 28 ; Split up the result and remainder RemainderBuffer rb 28 ; Split up the result and remainder CommaBuffer rb 38 ; thirty six bytes for DecimalBuffer information CommasNeeded rd 1 ; Saving commas needed TheRemainder rd 1 ; Saving the Remainder TheResult rd 1 ; Saving the Result OrderOfTens rd 1 ; Saving order of tens (10^n) ZeroNotLoaded rb 1 ; Used for checking zero starting numbers NumberOfRegisters rb 1 ; Used to determine number of registered displayed DivisorNumber rw 1 ; Used to keep track of division BigNumber rd 3 ; Save some room for 96 bits of number |
|||
21 Sep 2014, 20:12 |
|
smiddy 23 Sep 2014, 14:04
Lesson Learned: If a device function 0 is present, then you have to check all functions. Do not assume that once a function fails, that subsequent functions are not there, unless it is function 0 that fails.
I was finally able to enumerate the mass storage device, which was under function 5, with no function 4...weird! I had to change the above code significantly in order to get it working properly too...I'll post an update to that later once I get it to pause between pages, since it enumerates way more devices than are screen areas. I also want to look up for type 1 (and type 2) configuration areas. Anyhow, I now can ID my drives though enumeration. Next work on AHCI... |
|||
23 Sep 2014, 14:04 |
|
BAiC 23 Sep 2014, 22:18
what are you referring to by type 1 and 2?
|
|||
23 Sep 2014, 22:18 |
|
BAiC 23 Sep 2014, 23:31
nevermind.. been awhile since I last dealt with PCI enumeration.
|
|||
23 Sep 2014, 23:31 |
|
smiddy 24 Sep 2014, 03:34
|
|||
24 Sep 2014, 03:34 |
|
tom tobias 27 Sep 2014, 12:07
Well done smiddy, glad to learn that you are back at it, with your usual good humor, and excellent documentation skills.
looking forward to your next elaboration.... tom |
|||
27 Sep 2014, 12:07 |
|
smiddy 28 Sep 2014, 11:16
Thanks Tom!
Although, more of an embellishment than anything else, "...on the shoulders of giants!" |
|||
28 Sep 2014, 11:16 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.