OSDev.org

The Place to Start for Operating System Developers
It is currently Wed Apr 17, 2024 8:37 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: Unable to detect second PCI NIC on QEMU [resolved]
PostPosted: Wed Jun 20, 2018 4:43 pm 
Offline
Member
Member

Joined: Sun Feb 04, 2018 8:04 pm
Posts: 35
Help!

Does anybody have experience setting up multiple NICs on QEMU?

I develop on a windows environment for Intel. I have a 64 bit kernel that scans the PCI slots and will detect whichever FIRST model I specify on the QEMU command line. If I specify a second NIC, it is always ignored.

Any example command lines for multiple NICs would be greatly appreciated!

(There are several examples, but they are complicated! Using vlans, TUNs, etc -- AND they dont' work for me either).

I am running QEMU on Windows 10, eg:

This correctly detects the 8139 card on the PCI bus.
qemu-system-x86_64.exe" C:\_dev\_pet\src\makescripts\..\bin\bootable.raw -cpu qemu64,+pdpe1gb -m 256M -net nic,model=rtl8139

This correctly detects the 8254 card on the PCI bus.
qemu-system-x86_64.exe" C:\_dev\_pet\src\makescripts\..\bin\bootable.raw -cpu qemu64,+pdpe1gb -m 256M -net nic

These only show the first card specified; the second card is ignored:
qemu-system-x86_64.exe" C:\_dev\_pet\src\makescripts\..\bin\bootable.raw -cpu qemu64,+pdpe1gb -m 256M -net nic -net nic,model=rtl8139

qemu-system-x86_64.exe" C:\_dev\_pet\src\makescripts\..\bin\bootable.raw -cpu qemu64,+pdpe1gb -m 256M -net nic,model=rtl8139 -net nic

I have tried versions 2.11.0 and 2.12 of QEMU and both behave the same way.
I have tried the newer syntax for specifying network cards -- same result.

The documentation is a little sketchy, so any and all help appreciated!

_________________
Code or code not. There is no try.


Last edited by 0b1 on Sat Jun 23, 2018 6:43 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Unable to detect second PCI NIC on QEMU
PostPosted: Sat Jun 23, 2018 6:43 am 
Offline
Member
Member

Joined: Sun Feb 04, 2018 8:04 pm
Posts: 35
Update --

It turned out my PCI scan ended one device earlier than the second NIC's location.

Because my OS maxmizes use of registers over the stack, this led me to come up with a simplified PCI scan...

Code:

_pci64_scan:
   ;scans the PCI buses for devices and places the found bus/dev_slot/class_subclass into the PCI Map.
   ;inputs: none
   ;outputs: none
   ;scan can be simplified so that bus + dev are on the same 32 bit register using the mask below
   ; E000 0000 BBBB BBBB DDDD DFFF rrrr rr00   e=Enable Bit
   ; 1000 0000 0000 0000 0000 0000 0000 0000  0x‭80000000‬  <== first bus:device:function #
   ; 1000 0000 1111 1111 1111 1000 0000 0000  ‭0x80FFF800‬  <== last bus:device:function #
        ; assumes function 0 on each b:d.

   MOV RDI, PCI_MAP_ADDR            
   MOV ECX, 0x80000000               ;starting B:D:F, shifted
   .loop_next_device:                  
      MOV EAX, ECX       
      OR EAX, PCI_REGISTER_CLASS << 2               ;insert register to be queried
      CALL pci_read_register                  
      SHR EAX, 16                           ;Move the retrieved Class/Subclass code to AX
      CMP AX, 0xFFFF                             
      JE  .not_a_device                     
         MOV [RDI + pci_map_entry.class_sub], AX        
         MOV [RDI + pci_map_entry.location], ECX                   ;Store location word as-is. Saves bit shifting when reused
         MOV EAX, ECX       
         OR EAX, PCI_REGISTER_DEVICEID << 2
         CALL pci_read_register
         MOV [RDI + pci_map_entry.device_id], EAX
         ADD RDI, pci_map_entry_size
         CMP RDI, PCI_MAP_ADDR + (pci_map_entry_size * MAX_MAP_ENTRIES)
         JNL .loop_next_device_done               ;maximum map size reached, exit the loop
      .not_a_device:
      ADD ECX, 0x800                        ;next B:D:F
      CMP ECX, 0x80FFF800                                                        ;final B:D:F
      JNG .loop_next_device
   .loop_next_device_done:   
   RET
_pci64_scan_done:


pci_read_register:           
   ;inputs:
   ;   EAX:  BUS/DEVICE/SLOT/REGISTER
   ;outputs:
   ;    EAX:  register contents
   ; trashes:
   ;    DX   
   MOV DX, PCI_CONFIG_ADDRESS
   OUT DX, EAX
   MOV DX, PCI_CONFIG_DATA
   IN EAX, DX
   RET   
pci_read_register_done:



(iaw Defensive programming practice, called routines in my implementation do not save and restore registers. The calling code holds the responsibility for saving any registers it needs saved.)

_________________
Code or code not. There is no try.


Top
 Profile  
 
 Post subject: Re: Unable to detect second PCI NIC on QEMU [resolved]
PostPosted: Sat Jun 23, 2018 1:02 pm 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 1604
Assembly? Why? Besides, your code lacks support for multi-function devices. The logic is: Start at B:D:F 0, keep increasing the device part of that, but if you find a device with the MF bit set (bit 23 in register 3), you also query each function. Although you could just change your existing code to increase ECX by 0x100 if the MF bit is set, else by 0x800 (instead of using 0x800 always).

And while we're optimizing: It is probably safe to assume that the firmware already initialized all the PCI bridges, so from your perspective the bus numbers are just a block. Then it would be better not to query all the busses that don't exist, right? Therefore, start a variable "maxbus" at 0, and whenever you see a PCI bridge (class code 6), update maxbus to its subordinate bus if that is higher than maxbus. Then break out of the loop once all devices on maxbus are queried.

And your note regarding defensive programming only works if you practice what you preach. Right now, _pci64_scan does not save its registers before calling pci_read_register. That's just another reason to use C for this.

_________________
Carpe diem!


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 265 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group