Who's Online |
69 user(s) are online ( 52 user(s) are browsing Forums)
Members: 0
Guests: 69
more...
|
|
|
|
Re: PCI virtio driver development
|
Posted on: 11/21 11:40
#1
|
Just popping in 
|
@hans @balaton I don't have trouble getting the low level part setup. I have the device setup:
(qemu) info virtio-status /machine/peripheral-anon/device[3]/virtio-backend
/machine/peripheral-anon/device[3]/virtio-backend:
device_name: virtio-blk
device_id: 2
vhost_started: false
bus_name: (null)
broken: false
disabled: false
disable_legacy_check: false
started: true
use_started: true
start_on_kick: false
use_guest_notifier_mask: true
vm_running: true
num_vqs: 1
queue_sel: 0
isr: 0
endianness: big
status:
VIRTIO_CONFIG_S_ACKNOWLEDGE: Valid virtio device found,
VIRTIO_CONFIG_S_DRIVER: Guest OS compatible with device,
VIRTIO_CONFIG_S_FEATURES_OK: Feature negotiation complete,
VIRTIO_CONFIG_S_DRIVER_OK: Driver setup and ready
Guest features:
Host features:
VIRTIO_RING_F_EVENT_IDX: Used & avail. event fields enabled,
VIRTIO_RING_F_INDIRECT_DESC: Indirect descriptors supported,
VIRTIO_F_RING_RESET: Driver can reset a queue individually,
VIRTIO_F_VERSION_1: Device compliant for v1 spec (legacy),
VIRTIO_F_ANY_LAYOUT: Device accepts arbitrary desc. layouts,
VIRTIO_F_NOTIFY_ON_EMPTY: Notify when device runs out of avail. descs. on VQ
VHOST_USER_F_PROTOCOL_FEATURES: Vhost-user protocol features negotiation supported,
VIRTIO_BLK_F_CONFIG_WCE: Cache writeback and writethrough modes supported,
VIRTIO_BLK_F_FLUSH: Flush command supported,
VIRTIO_BLK_F_WRITE_ZEROES: Write zeroes command supported,
VIRTIO_BLK_F_DISCARD: Discard command supported,
VIRTIO_BLK_F_TOPOLOGY: Topology information available,
VIRTIO_BLK_F_BLK_SIZE: Block size of disk available,
VIRTIO_BLK_F_GEOMETRY: Legacy geometry available,
VIRTIO_BLK_F_SEG_MAX: Max segments in a request is seg_max
Backend features:
And I even setup a request in the queue:
(qemu) info virtio-queue-element /machine/peripheral-anon/device[3]/virtio-backend 0 0
Desc next is 768
/machine/peripheral-anon/device[3]/virtio-backend:
device_name: virtio-blk
index: 0
desc:
descs:
addr 0x471ad70 len 1 (write, next),
addr 0x4709ca0 len 7 (next),
addr 0x471ad60 len 16 (next)
avail:
flags: 0
idx: 0
ring: 0
used:
flags: 0
idx: 256
(qemu)
The "only" thing is, I cannot signal the device like described in chapter 4.1.4.4.1. I calculate the address, but writing any kind of value into that address location, results in nothing. No error message from qemu, no processing of the virtqueue entries. And yes the PCI command register has bit 2 set. So that's is where I need help, or least some kind of debug output telling my what qemu thinks is wrong. And yes I will contact Matthew. But I already had my code, a long time before the virtio.library was made public known.
|
|
|
|
Re: PCI virtio driver development
|
Posted on: 11/19 14:24
#2
|
Just popping in 
|
@balaton
The BAR mapping looks good, as long I understand everything.
I test all the options suggested. During the run of my test, no output was giving. Which makes me wonder because using "-trace enable="pci*"" only gives output during startup of the OS. But if I start my test, and it read in the pci configuration space. No additional message were written by this option.
Yeah, we should work together, but except Hans who is the third person? Any my code is just at the moment a hack done, to see how everything works.
|
|
|
|
PCI virtio driver development
|
Posted on: 11/19 12:10
#3
|
Just popping in 
|
Anyone having experience writing a AOS4 driver for a pci device? I'm trying to write a virtio-... device driver. Currently palying around with block device. So I'm setting up a simple test to write data. It seems from the qemu monitor everything is fine. But I'm struggling with kicking of the write request to the device. From the documentation, is should be quiet simple, just write a value to a specific address in the BAR region. I have that address, I know the value to write. But writing to that address, nothing happens.
Is there a trick form the AmigaOS side, and is there a way to debug/monitor that from the qemu side.
|
|
|
|
Re: gcc 9 and 10
|
Posted on: 11/13 19:16
#4
|
Just popping in 
|
@joerg Quote: Another reason .rodata should be separated from .text (and .plt) is the way (non-)execuable memory is allocated in AmigaOS 4.x. At least on some CPUs you can't change it after allocation from executable to non-executable, or the other way round.
So the best solution would be to always have .rodata section in its own segment , regardless of the type (executable, sjobs). This the elf.library allocate straight a head memory as described by the segments. No fancy splitting needed. And sjobs works, too. Quote: If you are developing a PPC library (AmigaOS foobar.library, not libfoobar.a or libfoobar.so) which also exists in a AmigaOS 3.x/m68k version and uses Hooks you will get m68k Hook functions from AmigaOS 3.x/m68k executables using the PPC version of the library on AmigaOS 4.x. The same is theoretically possible for m68k interrupts as well, but unlikely to be used.
Yes, but in this case I‘m not developing a sobj, but a foo.library. Which again doesn’t have a .plt section. So no m6ik code in sobj. BTW can foo.library use sjobs ?
|
|
|
|
Re: gcc 9 and 10
|
|
Just popping in 
|
@Futaura I think I understand, that the loading of elf files differs form the standard, is because of the fact that calling m68k should/must work, for normal executable. And the same loading behavior is applied to sobjs. And to workaround that .plt and .text section gets ripped apart, the solution is to have .rodata in its own segment. But must sobjs loading actually be handled like normal executable? Of course it is easier to have the same loading code for both. What I'm thinking of is, if it is possible for an sobj to have any m68k code? Sobjs are for ppc only, so the only way to "include" m68k code is to call it. In the Migration Guide are all? cases listed how to call m68k code: * m68k library: needs generated stubs, which are realizes as separate disk-resident file. So no m68k code in the sobjs * m68k Hook function: Theoretically possible, but why should I setup an m68k hook, if I currently developing for ppc. Maybe only used in a bizarre scenario * m68k interrupts: Same as m68k hook. Why use m68 code, if developing happens on ppc * calling emulator: Probably use case, which can happen. But the m68k code would normally be loaded from another file and not be as read only data. In later case the developer could just again use ppc instead of m68k during development. I think, there aren't any sobjs files having m68k code. And if there are some, than they are very rare and probably do other stuff, which isn't correct programming. I would like to know if someone can prove it wrong. Because if this assumption is valid, sobjs could just be loaded as described by elf. No special handling of .rodata is needed. On the other hand, the question must be answered if it worth the effort to have two loading mechanism in the elf.library, and if the elf.library knows if its loading an sobj file. If the later is not possible, this all is just an mind game.
|
|
|
|
Re: can anybody explain about current situation with BREL Relocations ?
|
|
Just popping in 
|
@Futaura
That would be very nice, if you could put together an example. What ever times it takes you. I'm in no hurry.
|
|
|
|
Re: gcc 9 and 10
|
|
Just popping in 
|
@Oliver
Around line 9345 the "magically" patch is made.
|
|
|
|
Re: gcc 9 and 10
|
|
Just popping in 
|
@Futaura The changes elfpipe did to support 0 value for the relocs were made because to support Template function argument changes address btw main exe and from inside shared object. As somewhere mention in the thread you referred to, it basically should go like that. If the value isn't 0 used that, else perform function address resolution. Lazy or not doesn't matter. How it should be done is even briefly/abstract described in the ABI. So you may "need" to read it to understand the code changes from elfpipe.
|
|
|
|
Re: gcc 9 and 10
|
|
Just popping in 
|
@Futaura See chapter 4.3.3 of e500 PPC ABI. Where information is written about dynamic linking of function addressee (st_value = 0) So from my point of view the zero in st_value is correct.
|
|
|
|
Re: gcc 9 and 10
|
Posted on: 9/24 16:00
#10
|
Just popping in 
|
@Futaura
Oh no It does even overlap! I see now that the Virtual addresses aren't "recalculated". I have to investigate that.
|
|
|
|
Re: gcc 9 and 10
|
Posted on: 9/24 15:57
#11
|
Just popping in 
|
@Futaura Ok, that was obviously. But it even output the debug message for other circumstances, where no overlap is (as long i can see, maybe i have a blind spot on this) and the .rodata section isn't in the segment like this from this debug output:
[Elf32_LoadSection] On Entry SectionIndex = 37 Filename = Work:1/test_dyn
[Elf32_LoadSection] sec = 0x60C11000
[Elf32_LoadProgramHeaders] File: Work:1/test_dyn
[Elf32_LoadProgramHeaders] Program Header offset: 0x00000034
[Elf32_LoadProgramHeaders] Program Header entrysize: 32
[Elf32_LoadProgramHeaders] Program Header array size: 6
[Elf32_LoadProgramHeaders] ProgHeader 0: Type 6
[Elf32_LoadProgramHeaders] Virtual: 0x01000034
[Elf32_LoadProgramHeaders] MemSize: 0x000000C0
[Elf32_LoadProgramHeaders] Flags: 0x00000004
[Elf32_LoadProgramHeaders] ProgHeader 1: Type 3
[Elf32_LoadProgramHeaders] Virtual: 0x010000F4
[Elf32_LoadProgramHeaders] MemSize: 0x00000011
[Elf32_LoadProgramHeaders] Flags: 0x00000004
[Elf32_LoadProgramHeaders] ProgHeader 2: Type 1
[Elf32_LoadProgramHeaders] Virtual: 0x01000000
[Elf32_LoadProgramHeaders] MemSize: 0x000050B0
[Elf32_LoadProgramHeaders] Flags: 0x00000005
[Elf32_LoadProgramHeaders] Ignoring this program header because we have an .rodata segment
[Elf32_LoadProgramHeaders] ProgHeader 3: Type 1
[Elf32_LoadProgramHeaders] Virtual: 0x01010000
[Elf32_LoadProgramHeaders] MemSize: 0x00000130
[Elf32_LoadProgramHeaders] Flags: 0x00000006
[Elf32_LoadProgramHeaders] Allocated 304 bytes for segment 0 at 0x60D907C0
[Elf32_LoadProgramHeaders] ProgHeader 4: Type 2
[Elf32_LoadProgramHeaders] Virtual: 0x01010010
[Elf32_LoadProgramHeaders] MemSize: 0x000000B8
[Elf32_LoadProgramHeaders] Flags: 0x00000006
[Elf32_LoadProgramHeaders] ProgHeader 5: Type 1
[Elf32_LoadProgramHeaders] Virtual: 0x01005000
[Elf32_LoadProgramHeaders] MemSize: 0x000000A5
[Elf32_LoadProgramHeaders] Flags: 0x00000004
[Elf32_LoadProgramHeaders] Ignoring this program header because we have an .rodata segment
and the segment / section stuff:
Segment Sections...
00
01 .interp
02 .interp .hash .dynsym .dynstr .rela.bss .rela.plt .text .plt .__newlib_version
03 .ctors .dtors .dynamic .data .got .sbss .bss
04 .dynamic
05 .rodata
So it must be something else which triggers even the debug output Quote: Ignoring this program header because we have an .rodata segment even that it doesn't overlap and no rodata section is present? Currently we are trying to put the .newlib_version section even add the end with .rodata together to see if we get other debug output for segment two.
|
|
|
|
Re: gcc 9 and 10
|
|
Just popping in 
|
@Futaura Thanks for the hint with the debug output for the elf.library. It gives more information, but still the picture isn't as clear as wanted. Because the message Quote: Ignoring this program header because we have an .rodata segment
Is even issued for program headers/segments which don't contain a .rodata section. So it must be more than just having a .rodata section in the segment, that the segment is handled differently. See we have the following segments/sections
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x01000034 0x01000034 0x000c0 0x000c0 R 0x4
INTERP 0x0000f4 0x010000f4 0x010000f4 0x00011 0x00011 R 0x1
[Requesting program interpreter: /usr/lib/ld.so.1]
LOAD 0x000000 0x01000000 0x01000000 0x050b0 0x050b0 R E 0x10000
LOAD 0x015000 0x01005000 0x01005000 0x000a5 0x000a5 R 0x10000
LOAD 0x020000 0x01010000 0x01010000 0x000d8 0x00130 RW 0x10000
DYNAMIC 0x020010 0x01010010 0x01010010 0x000b8 0x000b8 RW 0x4
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .hash .dynsym .dynstr .rela.bss .rela.plt .text .plt .__newlib_version
03 .rodata
04 .ctors .dtors .dynamic .data .got .sbss .bss
05 .dynamic
And this is the beginning of the elf.library debug output with two times the message
[Elf32_LoadSection] On Entry SectionIndex = 37 Filename = Work:2/test_dyn
[Elf32_LoadSection] sec = 0x5FFE9000
[Elf32_LoadProgramHeaders] File: Work:2/test_dyn
[Elf32_LoadProgramHeaders] Program Header offset: 0x00000034
[Elf32_LoadProgramHeaders] Program Header entrysize: 32
[Elf32_LoadProgramHeaders] Program Header array size: 6
[Elf32_LoadProgramHeaders] ProgHeader 0: Type 6
[Elf32_LoadProgramHeaders] Virtual: 0x01000034
[Elf32_LoadProgramHeaders] MemSize: 0x000000C0
[Elf32_LoadProgramHeaders] Flags: 0x00000004
[Elf32_LoadProgramHeaders] ProgHeader 1: Type 3
[Elf32_LoadProgramHeaders] Virtual: 0x010000F4
[Elf32_LoadProgramHeaders] MemSize: 0x00000011
[Elf32_LoadProgramHeaders] Flags: 0x00000004
[Elf32_LoadProgramHeaders] ProgHeader 2: Type 1
[Elf32_LoadProgramHeaders] Virtual: 0x01000000
[Elf32_LoadProgramHeaders] MemSize: 0x000050B0
[Elf32_LoadProgramHeaders] Flags: 0x00000005
[Elf32_LoadProgramHeaders] Ignoring this program header because we have an .rodata segment
[Elf32_LoadProgramHeaders] ProgHeader 3: Type 1
[Elf32_LoadProgramHeaders] Virtual: 0x01005000
[Elf32_LoadProgramHeaders] MemSize: 0x000000A5
[Elf32_LoadProgramHeaders] Flags: 0x00000004
[Elf32_LoadProgramHeaders] Ignoring this program header because we have an .rodata segment
[Elf32_LoadProgramHeaders] ProgHeader 4: Type 1
[Elf32_LoadProgramHeaders] Virtual: 0x01010000
[Elf32_LoadProgramHeaders] MemSize: 0x00000130
[Elf32_LoadProgramHeaders] Flags: 0x00000006
[Elf32_LoadProgramHeaders] Allocated 304 bytes for segment 0 at 0x61DCF040
[Elf32_LoadProgramHeaders] ProgHeader 5: Type 2
[Elf32_LoadProgramHeaders] Virtual: 0x01010010
[Elf32_LoadProgramHeaders] MemSize: 0x000000B8
[Elf32_LoadProgramHeaders] Flags: 0x00000006
[_elf32_ElfLoadSeg] Entry
[Elf32_LoadSection] On Entry SectionIndex = 35 Filename = Work:2/test_dyn
[Elf32_LoadSection] ehdr->e_shstrndx = 37, shdr->sh_name = 1
Even that the second output of the message can be explained with, what you sad: a .rodatas section in segment. The first message have been triggered by another condition. Could peek in the source of the elf.library and see if you find another/additional explaination?
|
|
|
|
Re: PCI device memory from BAR under qemu alwys zero
|
Posted on: 9/15 12:28
#13
|
Just popping in 
|
@Hans Yeap that made the trick:
pciDevice->WriteConfigWord( PCI_COMMAND,0x002 | pciDevice->ReadConfigWord( PCI_COMMAND ) );
Now i get other stuff than zeros!
|
|
|
|
Re: PCI device memory from BAR under qemu alwys zero
|
Posted on: 9/15 10:12
#14
|
Just popping in 
|
@Hans Quote: If it's the latter, then check whether the master and memory enable bits are set in the PCI_COMMAND register (enable I/O accesses too if you have an I/O BAR). You need to enable those bits in order to access the memory.
I think that could be what I'm missing. At least this I never read/heard of yet, compared to what balaton, jeorg etc wrote. That all I knew from the virtio spec etc. Another topic which comes to my mind. do I have take care of the cpu caches? Maybe I just writing/reading into/from the cache and the real memory isn't updated?
|
|
|
|
Re: PCI device memory from BAR under qemu alwys zero
|
Posted on: 9/14 14:20
#15
|
Just popping in 
|
I checked the address which i retrieved with the address from Ranger etc. This seems to be correct. And even running my test on a real machine, gives me even. nore zero values. I'm not sure what I'm doing wrong.
It might even be that on qemu the virtio device isn't yet correctly configure and this not data present. There might be issue with the synchronization between cpu and memory of the device. There are so many pitfalls.
Is there anywhere an simple example how to drive a device device? especially reading from the BAR memory? Or a tool known to work, which dumps BAR memory?
|
|
|
|
Re: PCI device memory from BAR under qemu alwys zero
|
Posted on: 9/13 16:10
#16
|
Just popping in 
|
@balaton
I read multiple times what you wrote and even found bit and pieces in the source of bboot. But I still no clue who and where to adopt the bar truncation in my setup with bboot and initrd Kickstart.zip file. Any example anywhere (expect as Hans mention buried deep done in the mention thread)
|
|
|
|
Re: PCI device memory from BAR under qemu alwys zero
|
Posted on: 9/13 10:09
#17
|
Just popping in 
|
@all A lot of information, which I currently cannot sort in. @Hans @joerg I'm using the Pegasos 2 emulation with bboot. I'm added the virtio devices as following to the working qemu call:
-device virtio-mouse-pci -device virtio-net-pci-non-transitional
I had the thought that qemu knows that "-m pegasos2" is 32bit, thus the virto devices will be 32bit too? So what do I have to tinker to get them mapped correctly? What kind of boot script?
|
|
|
|
Re: PCI device memory from BAR under qemu alwys zero
|
Posted on: 9/12 13:56
#18
|
Just popping in 
|
@geennaam I hope that the virtio-xx-pci devices are correctly emulated  At least all vendor specific capabilities etc I find, and can read. These have the following structure:
struct virtio_pci_cap
{
u8 cap_vndr; /* Generic PCI field: PCI_CAP_ID_VNDR */
u8 cap_next; /* Generic PCI field: next ptr. */
u8 cap_len; /* Generic PCI field: capability length */
u8 cfg_type; /* Identifies the structure. See VIRTIO_PCI_CAP_XXX below */
u8 bar; /* Where to find it. */
u8 id; /* Multiple capabilities of the same type */
u8 padding[2]; /* Pad to full dword. */
le32 bar_offset; /* Offset within bar. */
le32 bar_length; /* Length of the structure, in bytes. */
};
And all values I retrieve for them looks correct (and even don't consist only out of zeros)
Reading pci device capabilities
Found capability 0x09 at offset 132:
cap_vndr = 9
cap_next = 112
cap_len = 20
cfg_type = 5
bar = 0
offset = 0
length = 0
Found capability 0x09 at offset 112:
cap_vndr = 9
cap_next = 96
cap_len = 20
cfg_type = 2
bar = 4
offset = 12288
length = 4096
Found capability 0x09 at offset 96:
cap_vndr = 9
cap_next = 80
cap_len = 16
cfg_type = 4
bar = 4
offset = 8192
length = 4096
Found capability 0x09 at offset 80:
cap_vndr = 9
cap_next = 64
cap_len = 16
cfg_type = 3
bar = 4
offset = 4096
length = 4096
Found capability 0x09 at offset 64:
cap_vndr = 9
cap_next = 0
cap_len = 16
cfg_type = 1
bar = 4
offset = 0
length = 4096
Just that the bar memory is zeroed on qemu.
|
|
|
|
Re: PCI device memory from BAR under qemu alwys zero
|
Posted on: 9/12 12:50
#19
|
Just popping in 
|
@geennaam
Even using BaseAddress doesn't result in other values but zeros. But I think my problem is that i running under qemu.
Dumping memory on a real X5020 dumps even values other than zero.
BTW in which case you have to use the physical instead of the base address? (Even that they are most of time the same?)
|
|
|
|
PCI device memory from BAR under qemu alwys zero
|
Posted on: 9/12 10:33
#20
|
Just popping in 
|
Does anyone know how to read out the memory of an PIC device defined via a BAR? I find my PCI device and call on that the GetResourceRange, and dumps the memory like this:
struct PCIResourceRange *resourceRange = pciDevice->GetResourceRange( 4 );
if( resourceRange == NULL ) {
printf( "BAR number %u returned no valid resource range.\n",4 );
goto exit_lockPCIDevice;
}
void *p = (void*)(resourceRange->Physical);
display_mem( p,resourceRange->Size,32 );
pciDevice->FreeResourceRange( resourceRange );
exit_lockPCIDevice:
But regardless which PCI device and matching bar I choose. I always only read zeros. And at least for some device I know there must be some values presents. What am I missing?
Edited by MigthyMax on 2023/9/12 12:51:15
|
|
|
|