accessing the network card
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: accessing the network card
The reason nobody else comments is because nobody can fix problems that exist between the keyboard and chair.
If you really are a programmer, you know how to debug problems: Do it. Otherwise, you shouldn't develop an OS.
If you really are a programmer, you know how to debug problems: Do it. Otherwise, you shouldn't develop an OS.
Re: accessing the network card
I guess thats what the sole purpose of the forum is, to fix the problem between the chair and the keyboard.
Re: accessing the network card
Hi, sounds like you are trying to use memory that doesn't belong to you yet. Shouldn't you map the memory address first?
Visit the Montrom user page for more info.
Re: accessing the network card
But Combuster says that its not possible to access device memory registers when u run ur code from an existing OS. Anyway u mean accessing the address indirectly?
Re: accessing the network card
What existing OS? You stated, "when i jump from my bootloader to the c code". If you are booting your kernel on a live machine, then your kernel becomes the OS. If this has taken place, then you can certainly access that memory, but you probably need to map it first.aloktiagi wrote:Hi,
So how do i find out the I/O base address of a device when i jump from my bootloader to the c code without the OS being there i.e no lspci command!!!
Regards
Alok
Visit the Montrom user page for more info.
Re: accessing the network card
You really seem to be stuck and irritated. Perhaps it helps you to look at our code:
http://prettyos.svn.sourceforge.net/vie ... rnel/pci.c <--- look here deeply, that seems to be your weak point
http://prettyos.svn.sourceforge.net/vie ... /rtl8139.c
look there at the install routine (still not perfect, but it works)
In the install routine we map the MMIO address to a virtual address in our memory:
Allocation process:
http://prettyos.svn.sourceforge.net/vie ... l/paging.c:
do not forget to install the interrupt handler:
in rtl8139_handler:
If you study our code, then you should be able to make it going. We are not far, but we can PING our RTL8139.
http://prettyos.svn.sourceforge.net/vie ... rnel/pci.c <--- look here deeply, that seems to be your weak point
Code: Select all
// RTL 8139 network card
if ((pciDev_Array[number].deviceID == 0x8139))
{
install_RTL8139(number);
}
look there at the install routine (still not perfect, but it works)
In the install routine we map the MMIO address to a virtual address in our memory:
Code: Select all
BaseAddressRTL8139_MMIO = (uint32_t) paging_acquire_pcimem(BaseAddressRTL8139_MMIO);
printf("BaseAddressRTL8139_MMIO mapped to virtual address %X\n", BaseAddressRTL8139_MMIO);
http://prettyos.svn.sourceforge.net/vie ... l/paging.c:
Code: Select all
void* paging_acquire_pcimem(uint32_t phys_addr)
{
static uint8_t* virt = PCI_MEM_START;
if (virt == PCI_MEM_END)
panic_assert(__FILE__, __LINE__, "Not enough PCI-memory available");
uint32_t pagenr = (uint32_t)virt/PAGESIZE;
// Check the page table and setup the page
ASSERT(kernel_pd->tables[pagenr/1024]);
kernel_pd->tables[pagenr/1024]->pages[pagenr%1024] = phys_addr | MEM_PRESENT | MEM_WRITE | MEM_KERNEL;
uint8_t* ret = virt;
virt += PAGESIZE;
return ret;
}
Code: Select all
irq_install_handler(32 + pciDev_Array[number].irq, rtl8139_handler);
Code: Select all
printf("\nMAC Receiver: ");
for (int8_t i = 4; i < 10; i++)
{
printf("%y ", network_buffer[i]);
}
printf("MAC Transmitter: ");
for (int8_t i = 10; i < 16; i++)
{
printf("%y ", network_buffer[i]);
}
http://www.henkessoft.de/OS_Dev/OS_Dev3.htm (OSDEV)
http://www.c-plusplus.de/forum/viewforu ... is-62.html
irc.euirc.net #PrettyOS
http://www.c-plusplus.de/forum/viewforu ... is-62.html
irc.euirc.net #PrettyOS
Re: accessing the network card
@ehenkes: His weak point is that he is still very much a student. He needs to move at a much slower pace than this. He isn't even close to writing this driver yet, and you just handed him the complete answer!
Visit the Montrom user page for more info.
Re: accessing the network card
Perhaps posting the exact error message might help. A seg fault as an OS detail, you shouldnt be getting a seg fault if you have used the above code in your OS.aloktiagi wrote:But i'm getting a seg fault . Any idea why?
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Re: accessing the network card
Sorry for the confusion till now i was trying to run my code on a linux machine just to see how pci configuration space works. It was all fine till i tried accessing device memory!!(my bad).
Ok i tried my code on a machine just the bootloader and my c code. Now i get the correct values for device and vendor ID 167714E4 i.e BCM5751.
But when i reach my base registers BAR[0-5] i get all blank values on my display. Now why is this happening?
Ok i tried my code on a machine just the bootloader and my c code. Now i get the correct values for device and vendor ID 167714E4 i.e BCM5751.
But when i reach my base registers BAR[0-5] i get all blank values on my display. Now why is this happening?
Re: accessing the network card
Fine that you receive these two byte data vendorID deviceID
What about the other data with one byte?
classID
subclassID
interfaceID
revID
irq
Do you get them correctly?
bars is length 4 bytes and offset 0x10, 0x14, ...
Perhaps you read only one or two byte of them
check the following:
1) pci_config_read
2) in(long) that you use internally
cf. our pci.h/c and util.c or show your functions.
What about the other data with one byte?
classID
subclassID
interfaceID
revID
irq
Do you get them correctly?
bars is length 4 bytes and offset 0x10, 0x14, ...
Perhaps you read only one or two byte of them
check the following:
1) pci_config_read
2) in(long) that you use internally
cf. our pci.h/c and util.c or show your functions.
http://www.henkessoft.de/OS_Dev/OS_Dev3.htm (OSDEV)
http://www.c-plusplus.de/forum/viewforu ... is-62.html
irc.euirc.net #PrettyOS
http://www.c-plusplus.de/forum/viewforu ... is-62.html
irc.euirc.net #PrettyOS
Re: accessing the network card
Hi
My function call is like this (bus and device are hard coded!)
functions is:
inb and outb look like this
Previously i was using inl and outl instead of inb and outb in the function. Now i get the bar0 value as E4. This should be correct now? Thanks!!
My function call is like this (bus and device are hard coded!)
Code: Select all
bar0 = pci_config_read1(0x04,0x00,0x00,0x10);
Code: Select all
int pci_config_read1(int bus, int device, int func, int content)
{
int idx,tmp;
idx = 0x80000000 + ((bus&0xFF)<<16) + ((device&0x1F)<<11) + ((func&0x7)<<8) + (content&0xFC);
outb(0xCF8,idx);
tmp = inb(0xCFC);
return tmp;
}
Code: Select all
void outb(u16int port, u8int value)
{
asm volatile ("outb %1, %0" : : "dN" (port), "a" (value));
}
u8int inb(u16int port)
{
u8int ret;
asm volatile("inb %1, %0" : "=a" (ret) : "dN" (port));
return ret;
}
Re: accessing the network card
Nope. You need to write and read a whole unsigned integer (that's 32bits, should be u32int in your code) and the 32bit functions (inl, outl). Hint: your idx is 0x80000000 plus something else; that obviously doesn't fit into a byte .aloktiagi wrote:Hi
My function call is like this (bus and device are hard coded!)
functions is:Code: Select all
bar0 = pci_config_read1(0x04,0x00,0x00,0x10);
inb and outb look like thisCode: Select all
int pci_config_read1(int bus, int device, int func, int content) { int idx,tmp; idx = 0x80000000 + ((bus&0xFF)<<16) + ((device&0x1F)<<11) + ((func&0x7)<<8) + (content&0xFC); outb(0xCF8,idx); tmp = inb(0xCFC); return tmp; }
Previously i was using inl and outl instead of inb and outb in the function. Now i get the bar0 value as E4. This should be correct now? Thanks!!Code: Select all
void outb(u16int port, u8int value) { asm volatile ("outb %1, %0" : : "dN" (port), "a" (value)); } u8int inb(u16int port) { u8int ret; asm volatile("inb %1, %0" : "=a" (ret) : "dN" (port)); return ret; }
Re: accessing the network card
Hi
Yes true it shud be 32 bit and inl and outl need to be used but when i had used them the result of my BAR0 was empty.
Then ehenkes in his post told that
Yes true it shud be 32 bit and inl and outl need to be used but when i had used them the result of my BAR0 was empty.
Then ehenkes in his post told that
So i switched to inb and outb and got E4 as BAR0 address!!!Fine that you receive these two byte data vendorID deviceID
What about the other data with one byte?
classID
subclassID
interfaceID
revID
irq
Do you get them correctly?
bars is length 4 bytes and offset 0x10, 0x14, ...
Perhaps you read only one or two byte of them
Re: accessing the network card
First, 0xe4 is at the start of the memory (it's the 228th byte actually). So, no way your bar is 0xe4. Second, can you post your inl and outl? I think they are broken .aloktiagi wrote:Hi
Yes true it shud be 32 bit and inl and outl need to be used but when i had used them the result of my BAR0 was empty.
Then ehenkes in his post told that
So i switched to inb and outb and got E4 as BAR0 address!!!Fine that you receive these two byte data vendorID deviceID
What about the other data with one byte?
classID
subclassID
interfaceID
revID
irq
Do you get them correctly?
bars is length 4 bytes and offset 0x10, 0x14, ...
Perhaps you read only one or two byte of them
Re: accessing the network card
Hi,
inl and outl look like this
inl and outl look like this
Code: Select all
int inportl(int port)
{
int ret_val;
__asm__ volatile ("in %%dx,%%eax" : "=a" (ret_val) : "d"(port));
return ret_val;
}
void outportl(int port, int val)
{
__asm__ volatile ("outl %%eax,%%dx" : : "a"(val), "d"(port));
}