8 #define DMA_SIZE (0x2400)
\r
9 #define DMA_ADDRESS(c) ((c)*DMA_SIZE+0x500) //Save Space for IDT and BDA
\r
11 #define LOWB(x) ((x)&0xFF)
\r
12 #define HIB(x) (((x)>>8)&0xFF)
\r
13 #define HIW(x) (((x)>>16)&0xFFFF)
\r
22 // === PROTOTYPES ===
\r
23 int DMA_Install(char **Arguments);
\r
24 void DMA_SetChannel(int Channel, int length, int read);
\r
25 int DMA_ReadData(int channel, int count, void *buffer);
\r
26 int DMA_WriteData(int channel, int count, const void *buffer);
\r
28 // === CONSTANTS ===
\r
29 const Uint8 cMASKPORT [8] = { 0x0A, 0x0A, 0x0A, 0x0A, 0xD4, 0xD4, 0xD4, 0xD4 };
\r
30 const Uint8 cMODEPORT [8] = { 0x0B, 0x0B, 0x0B, 0x0B, 0xD6, 0xD6, 0xD6, 0xD6 };
\r
31 const Uint8 cCLEARPORT[8] = { 0x0C, 0x0C, 0x0C, 0x0C, 0xD8, 0xD8, 0xD8, 0xD8 };
\r
32 const Uint8 cPAGEPORT [8] = { 0x87, 0x83, 0x81, 0x82, 0x8F, 0x8B, 0x89, 0x8A };
\r
33 const Uint8 cADDRPORT [8] = { 0x00, 0x02, 0x04, 0x06, 0xC0, 0xC4, 0xC8, 0xCC };
\r
34 const Uint8 cCOUNTPORT[8] = { 0x01, 0x03, 0x05, 0x07, 0xC2, 0xC6, 0xCA, 0xCE };
\r
37 MODULE_DEFINE(0, 0x0100, x86_ISADMA, DMA_Install, NULL, NULL);
\r
38 char *dma_addresses[8];
\r
39 t_dmaChannel dma_channels[8];
\r
43 * \brief Initialise DMA channels
\r
44 * \param Arguments Arguments passed at boot time
\r
46 int DMA_Install(char **Arguments)
\r
51 outb( cMASKPORT[i], 0x04 | (i & 0x3) ); // mask channel
\r
52 outb( cCLEARPORT[i], 0x00 );
\r
53 outb( cMODEPORT[i], 0x48 | (i & 0x3) ); //Read Flag
\r
54 outb( 0xd8, 0xff); //Reset Flip-Flop
\r
55 outb( cADDRPORT[i], LOWB(DMA_ADDRESS(i)) ); // send address
\r
56 outb( cADDRPORT[i], HIB(DMA_ADDRESS(i)) ); // send address
\r
57 outb( 0xd8, 0xff); //Reset Flip-Flop
\r
58 outb( cCOUNTPORT[i], LOWB(DMA_SIZE) ); // send size
\r
59 outb( cCOUNTPORT[i], HIB(DMA_SIZE) ); // send size
\r
60 outb( cPAGEPORT[i], LOWB(HIW(DMA_ADDRESS(i))) ); // send page
\r
61 outb( cMASKPORT[i], i & 0x3 ); // unmask channel
\r
63 dma_channels[i].mode = 0;
\r
64 dma_addresses[i] = (char*)DMA_ADDRESS(i);
\r
65 dma_addresses[i] += KERNEL_BASE;
\r
67 return MODULE_ERR_OK;
\r
71 * \fn void DMA_SetChannel(int Channel, int length, int read)
\r
72 * \brief Set DMA Channel Length and RW
\r
74 void DMA_SetChannel(int Channel, int length, int read)
\r
76 Uint chan = Channel & 7;
\r
78 if(length > DMA_SIZE) length = DMA_SIZE;
\r
79 length --; //Adjust for DMA
\r
80 outb( cMASKPORT[chan], 0x04 | (chan & 0x3) ); // mask channel
\r
81 outb( cCLEARPORT[chan], 0x00 );
\r
82 outb( cMODEPORT[chan], (0x44 + (!read)*4) | (chan & 0x3) );
\r
83 outb( cADDRPORT[chan], LOWB(DMA_ADDRESS(chan)) ); // send address
\r
84 outb( cADDRPORT[chan], HIB(DMA_ADDRESS(chan)) ); // send address
\r
85 outb( cPAGEPORT[chan], HIW(DMA_ADDRESS(chan)) ); // send page
\r
86 outb( cCOUNTPORT[chan], LOWB(length) ); // send size
\r
87 outb( cCOUNTPORT[chan], HIB(length) ); // send size
\r
88 outb( cMASKPORT[chan], chan & 0x3 ); // unmask channel
\r
89 dma_addresses[chan] = (char*)DMA_ADDRESS(chan);
\r
90 dma_addresses[chan] += KERNEL_BASE;
\r
94 * \fn void DMA_ReadData(int channel, int count, void *buffer)
\r
95 * \brief Read data from a DMA buffer
\r
97 int DMA_ReadData(int channel, int count, void *buffer)
\r
99 if(channel < 0 || channel > 7)
\r
101 if(count < 0 || count > DMA_SIZE)
\r
103 //LogF("memcpy(*0x%x, dma_channels[channel].address, count)\n", buffer
\r
104 memcpy(buffer, dma_addresses[channel], count);
\r
109 * \fn void DMA_WriteData(int channel, int count, void *buffer)
\r
110 * \brief Write data to a DMA buffer
\r
112 int DMA_WriteData(int channel, int count, const void *buffer)
\r
114 if(channel < 0 || channel > 7)
\r
116 if(count < 0 || count > DMA_SIZE)
\r
119 memcpy(dma_addresses[channel], buffer, count);
\r