Sorting source tree a bit
[tpg/acess2.git] / KernelLand / Modules / x86 / ISADMA / dma.c
1 /*\r
2  * AcessOS 1.0\r
3  * DMA Driver\r
4  */\r
5 #include <acess.h>\r
6 #include <modules.h>\r
7 \r
8 #define DMA_SIZE        (0x2400)\r
9 #define DMA_ADDRESS(c)  ((c)*DMA_SIZE+0x500)    //Save Space for IDT and BDA\r
10 \r
11 #define LOWB(x) ((x)&0xFF)\r
12 #define HIB(x)  (((x)>>8)&0xFF)\r
13 #define HIW(x)  (((x)>>16)&0xFFFF)\r
14 \r
15 // === TYPES ===\r
16 typedef struct\r
17 {\r
18          int    mode;\r
19         char    *address;\r
20 } t_dmaChannel;\r
21 \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
27 \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
35 \r
36 // === GLOBALS ===\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
40 \r
41 // === CODE ===\r
42 /**\r
43  * \brief Initialise DMA channels\r
44  * \param Arguments     Arguments passed at boot time\r
45  */\r
46 int DMA_Install(char **Arguments)\r
47 {\r
48         Uint    i;\r
49         for(i=8;i--;)\r
50         {\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
62                 \r
63                 dma_channels[i].mode = 0;\r
64                 dma_addresses[i] = (char*)DMA_ADDRESS(i);\r
65                 dma_addresses[i] += KERNEL_BASE;\r
66         }\r
67         return MODULE_ERR_OK;\r
68 }\r
69 \r
70 /**\r
71  * \fn void DMA_SetChannel(int Channel, int length, int read)\r
72  * \brief Set DMA Channel Length and RW\r
73  */\r
74 void DMA_SetChannel(int Channel, int length, int read)\r
75 {\r
76         Uint    chan = Channel & 7;\r
77         read = !!read;\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
91 }\r
92 \r
93 /**\r
94  * \fn void DMA_ReadData(int channel, int count, void *buffer)\r
95  * \brief Read data from a DMA buffer\r
96  */\r
97 int DMA_ReadData(int channel, int count, void *buffer)\r
98 {\r
99         if(channel < 0 || channel > 7)\r
100                 return -1;\r
101         if(count < 0 || count > DMA_SIZE)\r
102                 return -2;\r
103         //LogF("memcpy(*0x%x, dma_channels[channel].address, count)\n", buffer\r
104         memcpy(buffer, dma_addresses[channel], count);\r
105         return 0;\r
106 }\r
107 \r
108 /**\r
109  * \fn void DMA_WriteData(int channel, int count, void *buffer)\r
110  * \brief Write data to a DMA buffer\r
111  */\r
112 int DMA_WriteData(int channel, int count, const void *buffer)\r
113 {\r
114         if(channel < 0 || channel > 7)\r
115                 return -1;\r
116         if(count < 0 || count > DMA_SIZE)\r
117                 return -2;\r
118         \r
119         memcpy(dma_addresses[channel], buffer, count);\r
120         \r
121         return 0;\r
122 }\r

UCC git Repository :: git.ucc.asn.au