Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
..........
unsigned long addrr_bar4 = results[0].pci_device->bar4;
................
else if((addrr_bar4 & 0x1) == 1)
{
//Save start port in an var and add the offset (Secondary ATA bus)
int port = (addrr_bar4 & 0xFFFFFFFC) + 8;
//Go to the port to which we have to send the ptr table address
port+=7;
//make sure it is an DWORD and store the address into the var address
unsigned long address_of_ptr = (int)ptr_table & 0xFFFFFFFF;
//Send the first byte of the address
outportb(port, address_of_ptr & 0xFF);
port--;
//Send the second byte of the address
outportb(port, (address_of_ptr >> 8)& 0xFF);
port--;
outportb(port, (address_of_ptr >> 16)& 0xFF);
port--;
//Send the last byte
outportb(port,(address_of_ptr >>24) & 0xFF);
//Set Command byte. To start and write
outportb((addrr_bar4 & 0xFFFFFFFC) + 8, 0x81 & 0xFF);
}
void DMA::setup_ptr_table(uint8_t count, unsigned long memory_space)
{
//set the value of the ptr table. Memory Space is the first DWORD. Count the next Word. Next word Reservt for MSB
//I was not sure if an unsigned char pointer can store an unsigned long var. So I wrote this. If he can only
*(ptr_table+3) = (unsigned char)(memory_space & 0xFF);
*(ptr_table+2) = (unsigned char)(memory_space >> 8);
*(ptr_table+1) = (unsigned char) (memory_space >> 16);
*ptr_table = (unsigned char) (memory_space >> 24);
//Set the next DWORD. First 16 bit are 0 (reserver MSB). The next is the count. A count of 0 means 64 k
//I was not sure if an unsigned char pointer can store an unsigned long var. So I wrote this. If he can only
*(ptr_table+5) = (unsigned char) (count & 0xff);
*(ptr_table +4) = (unsigned char)(count >> 8);
//Set MSB
*(ptr_table+6) = 0x00;
*(ptr_table+7) = 0x00;
*(ptr_table+8) = '\0';
}
Are you using virtual memory at all? If so, you need to use a physical address when talking to the device, and a virtual address when manipulating the data. DMA doesn't go through the MMU - it hits the memory directly.
Only to make sure that I have the table with the I/O Ports understand right and the progam only does not work because I wrote to the wrong ports :
Bar4: 4-Byte Aligned Base Address of Bar 4 register. (Bar 4 & 0xFFFFFFFC)
Primary IDE channel
Bar4 | is the command port
Bar 4 + 0x2 | is the Status Port
Bar 4 + 0x4 |Port to send the first Byte of the PRDT Address
Bar 4 + 0x5 | Port to send the second Byte of the PRDT Address
.......................................
Second IDE channel
Bar4 + 0x8 | is the Command I/o port
Bar4 + 0xA | is the I/O port form which I can read the Status
Bar 0xC | Port to send the first byte of the PRDT Address
I sure hope you use the actual base address of 0xc000 (see PCI)
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
if it is an Memory Space BAR Layout or I/O Space BAR Layout. If it is an I/O space layout I calculate addrr_bar4 & 0xFFFFFFFC to get the base port. Othercase I would calculate Bar & 0xFFFFFFF0 to get the base address .
But if bar4 has the value c001 it should be an I/O Space BAR Layout
yes it should be (also, that C code is wrong, the & operator has a lower precedence than == for some reason, so the correct code is (addrr_bar4 & 0x1) == 1
thepowersgang wrote:yes it should be (also, that C code is wrong, the & operator has a lower precedence than == for some reason, so the correct code is (addrr_bar4 & 0x1) == 1
I uses it right for checking if it is Memory Mapt or an I/O port but for the function which check for an error in DMA I forgot the () . Thx did not know that .
There was some other errors in the code and I make it easier (I use union now). I did not get the cd Driver to work right now but no function which check if with DMA everything work right "return false" (I hope there are no errors in these functions) . So I think with DMA is now everything right. If I get other problems with DMA I will repost. THX to all
Hi
i did not get an IRQ after I send the atapi read command(0xA8). I think the reason for that is that the 0x3C PCI register has the value 0xffffff.. So no conection with the Interrupt Line. But also the Bit 0 of the Status register did not change to 0, which means last entry of prdt table is read.
Can someone pls check if my error methods are so far right so that I really know that with DMA is all right. And I have to search the error in Atapi
Bit 1 (value = 2) is set if any DMA memory transfer failed for any reason in this PRDT.