Page 3 of 4
Re: accessing the network card
Posted: Sat May 15, 2010 10:19 am
by Combuster
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.
Re: accessing the network card
Posted: Sat May 15, 2010 10:38 am
by aloktiagi
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
Posted: Sat May 15, 2010 4:28 pm
by montrom
Hi, sounds like you are trying to use memory that doesn't belong to you yet. Shouldn't you map the memory address first?
Re: accessing the network card
Posted: Sun May 16, 2010 12:53 am
by aloktiagi
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
Posted: Sun May 16, 2010 1:12 am
by montrom
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
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.
Re: accessing the network card
Posted: Sun May 16, 2010 6:24 pm
by ehenkes
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
Code: Select all
// RTL 8139 network card
if ((pciDev_Array[number].deviceID == 0x8139))
{
install_RTL8139(number);
}
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:
Code: Select all
BaseAddressRTL8139_MMIO = (uint32_t) paging_acquire_pcimem(BaseAddressRTL8139_MMIO);
printf("BaseAddressRTL8139_MMIO mapped to virtual address %X\n", BaseAddressRTL8139_MMIO);
Allocation process:
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;
}
do not forget to install the interrupt handler:
Code: Select all
irq_install_handler(32 + pciDev_Array[number].irq, rtl8139_handler);
in 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]);
}
If you study our code, then you should be able to make it going. We are not far, but we can PING our RTL8139.
Re: accessing the network card
Posted: Sun May 16, 2010 6:56 pm
by montrom
@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!
Re: accessing the network card
Posted: Sun May 16, 2010 7:45 pm
by neon
aloktiagi wrote:But i'm getting a seg fault
. Any idea why?
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.
Re: accessing the network card
Posted: Mon May 17, 2010 9:08 am
by aloktiagi
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?
Re: accessing the network card
Posted: Tue May 18, 2010 5:04 pm
by ehenkes
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.
Re: accessing the network card
Posted: Tue May 18, 2010 9:59 pm
by aloktiagi
Hi
My function call is like this (bus and device are hard coded!)
Code: Select all
bar0 = pci_config_read1(0x04,0x00,0x00,0x10);
functions is:
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;
}
inb and outb look like this
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;
}
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!!
Re: accessing the network card
Posted: Thu May 20, 2010 5:38 am
by eddyb
aloktiagi wrote:Hi
My function call is like this (bus and device are hard coded!)
Code: Select all
bar0 = pci_config_read1(0x04,0x00,0x00,0x10);
functions is:
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;
}
inb and outb look like this
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;
}
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!!
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
.
Re: accessing the network card
Posted: Thu May 20, 2010 5:54 am
by aloktiagi
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
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
So i switched to inb and outb and got E4 as BAR0 address!!!
Re: accessing the network card
Posted: Thu May 20, 2010 10:36 pm
by eddyb
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
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
So i switched to inb and outb and got E4 as BAR0 address!!!
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
.
Re: accessing the network card
Posted: Fri May 21, 2010 12:42 am
by aloktiagi
Hi,
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));
}