8a6ef22ef60a40885249b49ddee0c4cf6e8fe027
[tpg/acess2.git] / Modules / Interfaces / EDI / edi_io.inc.c
1 /*
2  * AcessOS EDI Interface
3  * - IO Port Class
4  * 
5  * By John Hodge (thePowersGang)
6  * 
7  * This file has been released into the public domain.
8  * You are free to use it as you wish.
9  */
10 #include "edi/edi.h"
11
12 // === TYPES ===
13 typedef struct {
14         uint16_t        State;  // 0: Unallocated, 1: Allocated, 2: Initialised, (Bit 0x8000 set if in heap)
15         uint16_t        Num;
16 } tEdiPort;
17
18 // === GLOBALS ===
19 #define NUM_PREALLOC_PORTS      128
20 tEdiPort        gEdi_PortObjects[NUM_PREALLOC_PORTS];
21
22 // === FUNCTIONS ===
23 /**
24  * \fn object_pointer Edi_Int_IO_Construct(void)
25  * \brief Creates a new IO Port Object
26  * \return      Pointer to object
27  */
28 object_pointer Edi_Int_IO_Construct(void)
29 {
30         tEdiPort        *ret;
31          int    i;
32         // Search for a free preallocated port
33         for( i = 0; i < NUM_PREALLOC_PORTS; i ++ )
34         {
35                 if(gEdi_PortObjects[i].State)   continue;
36                 gEdi_PortObjects[i].State = 1;
37                 gEdi_PortObjects[i].Num = 0;
38                 return &gEdi_PortObjects[i];
39         }
40         // Else, use heap space
41         ret = malloc( sizeof(tEdiPort) );
42         ret->State = 0x8001;
43         ret->Num = 0;
44         return ret;
45 }
46
47 /**
48  * \fn void Edi_Int_IO_Destruct(object_pointer Object)
49  * \brief Destruct an IO Port Object
50  * \param Object        Object to destroy
51  */
52 void Edi_Int_IO_Destruct(object_pointer Object)
53 {
54         tEdiPort        *obj;
55         // Get Data Pointer
56         VALIDATE_PTR(Object,);
57         obj = GET_DATA(Object);
58         
59         if(obj->State & 0x8000) {       // If in heap, free
60                 free(Object);
61         } else {        // Otherwise, mark as unallocated
62                 obj->State = 0;
63         }
64 }
65
66 /**
67  * \fn int32_t  Edi_Int_IO_InitPort(object_pointer Object, uint16_t Port)
68  * \brief Initialises an IO Port
69  * \param Object        Object Pointer (this)
70  * \param Port  Port Number to use
71  */
72 int32_t Edi_Int_IO_InitPort(object_pointer Object, uint16_t Port)
73 {
74         tEdiPort        *obj;
75         // Get Data Pointer
76         VALIDATE_PTR(Object, 0);
77         obj = GET_DATA(Object);
78         
79         if( !obj->State )       return 0;
80         obj->Num = Port;
81         obj->State &= ~0x3FFF;
82         obj->State |= 2;        // Set initialised flag
83         return 1;
84 }
85
86 /**
87  * \fn uint16_t Edi_Int_IO_GetPortNum(object_pointer Object)
88  * \brief Returns the port number associated with the object
89  * \param Object        Port Object to get number from
90  * \return Port Number
91  */
92 uint16_t Edi_Int_IO_GetPortNum(object_pointer Object)
93 {
94         tEdiPort        *obj;
95         // Get Data Pointer
96         VALIDATE_PTR(Object, 0);
97         obj = GET_DATA(Object);
98         // Check if valid
99         if( !obj->State )       return 0;
100         // Return Port No
101         return obj->Num;
102 }
103
104 /**
105  * \fn int32_t Edi_Int_IO_ReadByte(object_pointer Object, uint8_t *out)
106  * \brief Read a byte from an IO port
107  * \param Object        Port Object
108  * \param out   Pointer to put read data
109  */
110 int32_t Edi_Int_IO_ReadByte(object_pointer Object, uint8_t *out)
111 {
112         tEdiPort        *obj;
113         // Get Data Pointer
114         VALIDATE_PTR(Object, 0);
115         obj = GET_DATA(Object);
116         
117         if( !obj->State )       return 0;
118         if( obj->State & 1 )    return -1;      // Unintialised
119         
120         __asm__ __volatile__ ( "inb %%dx, %%al" : "=a" (*out) : "d" ( obj->Num ) );
121         
122         return 1;
123 }
124
125 /**
126  * \fn int32_t Edi_Int_IO_ReadWord(object_pointer Object, uint16_t *out)
127  * \brief Read a word from an IO port
128  * \param Object        Port Object
129  * \param out   Pointer to put read data
130  */
131 int32_t Edi_Int_IO_ReadWord(object_pointer Object, uint16_t *out)
132 {
133         
134         tEdiPort        *obj;
135         // Get Data Pointer
136         VALIDATE_PTR(Object, 0);
137         obj = GET_DATA(Object);
138         if( !obj->State )       return 0;
139         if( obj->State & 1 )    return -1;      // Unintialised
140         
141         __asm__ __volatile__ ( "inw %%dx, %%ax" : "=a" (*out) : "d" ( obj->Num ) );
142         
143         return 1;
144 }
145
146 /**
147  * \fn int32_t Edi_Int_IO_ReadDWord(object_pointer Object, uint32_t *out)
148  * \brief Read a double word from an IO port
149  * \param Object        Port Object
150  * \param out   Pointer to put read data
151  */
152 int32_t Edi_Int_IO_ReadDWord(object_pointer Object, uint32_t *out)
153 {
154         
155         tEdiPort        *obj;
156         // Get Data Pointer
157         VALIDATE_PTR(Object, 0);
158         obj = GET_DATA(Object);
159         if( !obj->State )       return 0;
160         if( obj->State & 1 )    return -1;      // Unintialised
161         
162         __asm__ __volatile__ ( "inl %%dx, %%eax" : "=a" (*out) : "d" ( obj->Num ) );
163         
164         return 1;
165 }
166
167 /**
168  * \fn int32_t Edi_Int_IO_ReadQWord(object_pointer Object, uint64_t *out)
169  * \brief Read a quad word from an IO port
170  * \param Object        Port Object
171  * \param out   Pointer to put read data
172  */
173 int32_t Edi_Int_IO_ReadQWord(object_pointer Object, uint64_t *out)
174 {
175         uint32_t        *out32 = (uint32_t*)out;
176         tEdiPort        *obj;
177         // Get Data Pointer
178         VALIDATE_PTR(Object, 0);
179         obj = GET_DATA(Object);
180         if( !obj->State )       return 0;
181         if( obj->State & 1 )    return -1;      // Unintialised
182         
183         __asm__ __volatile__ ( "inl %%dx, %%eax" : "=a" (*out32) : "d" ( obj->Num ) );
184         __asm__ __volatile__ ( "inl %%dx, %%eax" : "=a" (*(out32+1)) : "d" ( obj->Num+4 ) );
185         
186         return 1;
187 }
188
189 /**
190  * \fn int32_t Edi_Int_IO_ReadString(object_pointer Object, uint32_t Length, uint8_t *out)
191  * \brief Read a byte from an IO port
192  * \param Object        Port Object
193  * \param Length        Number of bytes to read
194  * \param out   Pointer to put read data
195  */
196 int32_t Edi_Int_IO_ReadString(object_pointer Object, uint32_t Length, uint8_t *out)
197 {
198         tEdiPort        *obj;
199         // Get Data Pointer
200         VALIDATE_PTR(Object, 0);
201         obj = GET_DATA(Object);
202         if( !obj->State )       return 0;
203         if( obj->State & 1 )    return -1;      // Unintialised
204         
205         __asm__ __volatile__ ( "rep insb" : : "c" (Length), "D" (out), "d" ( obj->Num ) );
206         
207         return 1;
208 }
209
210 /**
211  * \fn int32_t Edi_Int_IO_WriteByte(object_pointer Object, uint8_t in)
212  * \brief Write a byte from an IO port
213  * \param Object        Port Object
214  * \param in    Data to write
215  */
216 int32_t Edi_Int_IO_WriteByte(object_pointer Object, uint8_t in)
217 {
218         tEdiPort        *obj;
219         // Get Data Pointer
220         VALIDATE_PTR(Object, 0);
221         obj = GET_DATA(Object);
222         if( !obj->State )       return 0;
223         if( obj->State & 1 )    return -1;      // Unintialised
224         
225         __asm__ __volatile__ ( "outb %%al, %%dx" : : "a" (in), "d" ( obj->Num ) );
226         
227         return 1;
228 }
229
230 /**
231  * \fn int32_t Edi_Int_IO_WriteWord(object_pointer Object, uint16_t in)
232  * \brief Write a word from an IO port
233  * \param Object        Port Object
234  * \param in    Data to write
235  */
236 int32_t Edi_Int_IO_WriteWord(object_pointer Object, uint16_t in)
237 {
238         tEdiPort        *obj;
239         // Get Data Pointer
240         VALIDATE_PTR(Object, 0);
241         obj = GET_DATA(Object);
242         if( !obj->State )       return 0;
243         if( obj->State & 1 )    return -1;      // Unintialised
244         
245         __asm__ __volatile__ ( "outw %%ax, %%dx" : : "a" (in), "d" ( obj->Num ) );
246         
247         return 1;
248 }
249
250 /**
251  * \fn int32_t Edi_Int_IO_WriteDWord(object_pointer Object, uint32_t in)
252  * \brief Write a double word from an IO port
253  * \param Object        Port Object
254  * \param in    Data to write
255  */
256 int32_t Edi_Int_IO_WriteDWord(object_pointer Object, uint32_t in)
257 {
258         tEdiPort        *obj;
259         // Get Data Pointer
260         VALIDATE_PTR(Object, 0);
261         obj = GET_DATA(Object);
262         if( !obj->State )       return 0;
263         if( obj->State & 1 )    return -1;      // Unintialised
264         
265         __asm__ __volatile__ ( "outl %%eax, %%dx" : : "a" (in), "d" ( obj->Num ) );
266         
267         return 1;
268 }
269
270 /**
271  * \fn int32_t Edi_Int_IO_WriteQWord(object_pointer Object, uint64_t in)
272  * \brief Write a quad word from an IO port
273  * \param Object        Port Object
274  * \param in    Data to write
275  */
276 int32_t Edi_Int_IO_WriteQWord(object_pointer Object, uint64_t in)
277 {
278         uint32_t        *in32 = (uint32_t*)&in;
279         tEdiPort        *obj;
280         // Get Data Pointer
281         VALIDATE_PTR(Object, 0);
282         obj = GET_DATA(Object);
283         if( !obj->State )       return 0;
284         if( obj->State & 1 )    return -1;      // Unintialised
285         
286         __asm__ __volatile__ ( "outl %%eax, %%dx" : : "a" (*in32), "d" ( obj->Num ) );
287         __asm__ __volatile__ ( "outl %%eax, %%dx" : : "a" (*(in32+1)), "d" ( obj->Num+4 ) );
288         
289         return 1;
290 }
291
292 /**
293  * \fn int32_t Edi_Int_IO_WriteString(object_pointer Object, uint32_t Length, uint8_t *in)
294  * \brief Read a byte from an IO port
295  * \param Object        Port Object
296  * \param Length        Number of bytes to write
297  * \param in    Pointer to of data to write
298  */
299 int32_t Edi_Int_IO_WriteString(object_pointer Object, uint32_t Length, uint8_t *in)
300 {
301         tEdiPort        *obj;
302         // Get Data Pointer
303         VALIDATE_PTR(Object, 0);
304         obj = GET_DATA(Object);
305         if( !obj->State )       return 0;
306         if( obj->State & 1 )    return -1;      // Unintialised
307         
308         __asm__ __volatile__ ( "rep outsb" : : "c" (Length), "D" (in), "d" ( obj->Num ) );
309         
310         return 1;
311 }
312
313 // === CLASS DECLARATION ===
314 /*static edi_variable_declaration_t     *scEdi_Int_Variables_IO[] = {
315         {
316                 {"pointer", "port_object", 0},
317                 {"uint16_t", "port", 0}
318         },
319         {
320                 {"pointer", "port_object", 0}
321         },
322         {
323                 {"pointer", "port_object", 0},
324                 {"pointer int8_t", "out", 0}
325         }
326 };*/
327 static edi_function_declaration_t       scEdi_Int_Functions_IO[] = {
328                 {"int32_t", "init_io_port", 1, 2, NULL, //scEdi_Int_Variables_IO[0],
329                         (function_pointer)Edi_Int_IO_InitPort
330                         },
331                 {"uint16_t", "get_port_number", 1, 1, NULL, //scEdi_Int_Variables_IO[1],
332                         (function_pointer)Edi_Int_IO_GetPortNum
333                         },
334                 {"int32_t", "read_byte_io_port", 1, 2, NULL, //scEdi_Int_Variables_IO[2],
335                         (function_pointer)Edi_Int_IO_ReadByte
336                         },
337                 {"int32_t", "read_word_io_port", 1, 2, NULL/*{
338                                 {"pointer", "port_object", 0},
339                                 {"pointer int16_t", "out", 0}
340                         }*/,
341                         (function_pointer)Edi_Int_IO_ReadWord
342                         },
343                 {"int32_t", "read_long_io_port", 1, 2, NULL/*{
344                                 {"pointer", "port_object", 0},
345                                 {"pointer int32_t", "out", 0}
346                         }*/,
347                         (function_pointer)Edi_Int_IO_ReadDWord
348                         },
349                 {"int32_t", "read_longlong_io_port", 1, 2, NULL/*{
350                                 {"pointer", "port_object", 0},
351                                 {"pointer int64_t", "out", 0}
352                         }*/,
353                         (function_pointer)Edi_Int_IO_ReadQWord
354                         },
355                 {"int32_t", "read_string_io_port", 1, 3, NULL/*{
356                                 {"pointer", "port_object", 0},
357                                 {"int32_T", "data_length", 0},
358                                 {"pointer int64_t", "out", 0}
359                         }*/,
360                         (function_pointer)Edi_Int_IO_ReadString
361                         },
362                         
363                 {"int32_t", "write_byte_io_port", 1, 2, NULL/*{
364                                 {"pointer", "port_object", 0},
365                                 {"int8_t", "in", 0}
366                         }*/,
367                         (function_pointer)Edi_Int_IO_WriteByte},
368                 {"int32_t", "write_word_io_port", 1, 2, NULL/*{
369                                 {"pointer", "port_object", 0},
370                                 {"int16_t", "in", 0}
371                         }*/,
372                         (function_pointer)Edi_Int_IO_WriteWord},
373                 {"int32_t", "write_long_io_port", 1, 2, NULL/*{
374                                 {"pointer", "port_object", 0},
375                                 {"int32_t", "in", 0}
376                         }*/,
377                         (function_pointer)Edi_Int_IO_WriteDWord},
378                 {"int32_t", "write_longlong_io_port", 1, 2, NULL/*{
379                                 {"pointer", "port_object", 0},
380                                 {"int64_t", "in", 0}
381                         }*/,
382                         (function_pointer)Edi_Int_IO_WriteQWord}
383         };
384 static edi_class_declaration_t  scEdi_Int_Class_IO = 
385         {
386                 IO_PORT_CLASS, 1, 12,
387                 scEdi_Int_Functions_IO,
388                 Edi_Int_IO_Construct,
389                 Edi_Int_IO_Destruct,
390                 NULL
391         };

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