Misc Changes, Added Logging Subsystem, Fixes to InitRD, Working on RTL8139 driver
[tpg/acess2.git] / Kernel / logging.c
1 /*
2  * Acess 2 Kernel
3  * - By John Hodge (thePowersGang)
4  *
5  * logging.c - Kernel Logging Service
6  */
7 #include <acess.h>
8
9 #define PRINT_ON_APPEND 1
10
11 // === CONSTANTS ===
12 enum eLogLevels
13 {
14         LOG_LEVEL_KPANIC,
15         LOG_LEVEL_PANIC,
16         LOG_LEVEL_FATAL,
17         LOG_LEVEL_ERROR,
18         LOG_LEVEL_WARNING,
19         LOG_LEVEL_NOTICE,
20         LOG_LEVEL_LOG,
21         LOG_LEVEL_DEBUG,
22         NUM_LOG_LEVELS
23 };
24 const char      csaLevelCodes[] = {'k','p','f','e','w','n','l','d'};
25
26 // === TYPES ===
27 typedef struct sLogEntry
28 {
29         struct sLogEntry        *Next;
30         struct sLogEntry        *LevelNext;
31         Sint64  Time;
32         Uint64  Ident;
33          int    Level;
34          int    Length;
35         char    Data[];
36 }       tLogEntry;
37 typedef struct sLogList
38 {
39         tLogEntry       *Head;
40         tLogEntry       *Tail;
41 }       tLogList;
42
43 // === PROTOTYPES ===
44 void    Log_AddEvent(char *Ident, int Level, char *Format, va_list Args);
45 static void     Log_Int_PrintMessage(tLogEntry *Entry);
46 void    Log_KernelPanic(char *Ident, char *Message, ...);
47 void    Log_Panic(char *Ident, char *Message, ...);
48 void    Log_Error(char *Ident, char *Message, ...);
49 void    Log_Warning(char *Ident, char *Message, ...);
50 void    Log_Log(char *Ident, char *Message, ...);
51 void    Log_Notice(char *Ident, char *Message, ...);
52 void    Log_Debug(char *Ident, char *Message, ...);
53 static Uint64   Log_Int_GetIdent(const char *Str);
54
55 // === GLOBALS ===
56 tSpinlock       glLog;
57 tLogList        gLog;
58 tLogList        gLog_Levels[NUM_LOG_LEVELS];
59
60 // === CODE ===
61 /**
62  * \brief Adds an event to the log
63  */
64 void Log_AddEvent(char *Ident, int Level, char *Format, va_list Args)
65 {
66          int    len;
67         tLogEntry       *ent;
68         Uint64  ident = Log_Int_GetIdent(Ident);
69         
70         if( Level >= NUM_LOG_LEVELS )   return;
71         
72         len = vsnprintf(NULL, 256, Format, Args);
73         
74         ent = malloc(sizeof(tLogEntry)+len+1);
75         ent->Time = now();
76         ent->Ident = ident;
77         ent->Level = Level;
78         ent->Length = len;
79         vsnprintf( ent->Data, 256, Format, Args );
80         
81         LOCK( &glLog );
82         
83         ent->Next = gLog.Tail;
84         if(gLog.Head)
85                 gLog.Tail = ent;
86         else
87                 gLog.Tail = gLog.Head = ent;
88         
89         ent->LevelNext = gLog_Levels[Level].Tail;
90         if(gLog_Levels[Level].Head)
91                 gLog_Levels[Level].Tail = ent;
92         else
93                 gLog_Levels[Level].Tail = gLog_Levels[Level].Head = ent;
94         
95         RELEASE( &glLog );
96         
97         #if PRINT_ON_APPEND
98         Log_Int_PrintMessage( ent );
99         #endif
100         
101 }
102
103 /**
104  * \brief Prints a log message to the debug console
105  */
106 void Log_Int_PrintMessage(tLogEntry *Entry)
107 {
108         LogF("%018%c [%8s] %s\n",
109                 Entry->Time,
110                 csaLevelCodes[Entry->Level],
111                 &Entry->Ident,
112                 Entry->Data
113                 );
114 }
115
116 /**
117  * \brief KERNEL PANIC!!!!
118  */
119 void Log_KernelPanic(char *Ident, char *Message, ...)
120 {
121         va_list args;   
122         va_start(args, Message);
123         Log_AddEvent(Ident, LOG_LEVEL_KPANIC, Message, args);
124         va_end(args);
125 }
126
127 /**
128  * \brief Panic Message - Driver Unrecoverable error
129  */
130 void Log_Panic(char *Ident, char *Message, ...)
131 {
132         va_list args;   
133         va_start(args, Message);
134         Log_AddEvent(Ident, LOG_LEVEL_PANIC, Message, args);
135         va_end(args);
136 }
137
138 /**
139  * \brief Error Message - Recoverable Error
140  */
141 void Log_Error(char *Ident, char *Message, ...)
142 {
143         va_list args;   
144         va_start(args, Message);
145         Log_AddEvent(Ident, LOG_LEVEL_ERROR, Message, args);
146         va_end(args);
147 }
148
149 /**
150  * \brief Warning Message - Something the user should know
151  */
152 void Log_Warning(char *Ident, char *Message, ...)
153 {
154         va_list args;
155         
156         va_start(args, Message);
157         Log_AddEvent(Ident, LOG_LEVEL_WARNING, Message, args);
158         va_end(args);
159 }
160
161 /**
162  * \brief Notice Message - Something the user might like to know
163  */
164 void Log_Notice(char *Ident, char *Message, ...)
165 {
166         va_list args;   
167         va_start(args, Message);
168         Log_AddEvent(Ident, LOG_LEVEL_NOTICE, Message, args);
169         va_end(args);
170 }
171
172 /**
173  * \brief Log Message - Possibly useful information
174  */
175 void Log_Log(char *Ident, char *Message, ...)
176 {
177         va_list args;   
178         va_start(args, Message);
179         Log_AddEvent(Ident, LOG_LEVEL_LOG, Message, args);
180         va_end(args);
181 }
182
183 /**
184  * \brief Debug Message - Only a developer would want this info
185  */
186 void Log_Debug(char *Ident, char *Message, ...)
187 {
188         va_list args;   
189         va_start(args, Message);
190         Log_AddEvent(Ident, LOG_LEVEL_DEBUG, Message, args);
191         va_end(args);
192 }
193
194 /**
195  * \brief Converts a string into a 64-bit ident
196  */
197 static Uint64 Log_Int_GetIdent(const char *Str)
198 {
199         Uint64  ret = 0;
200          int    i;
201         char    ch;
202         
203         for( i = 0; Str[i] && i < 7; i++ )
204         {
205                 ch = Str[i];
206                 
207                 if(ch < ' ')
208                         ch = '?';
209                 else if(ch > '~')
210                         ch = '?';
211                 
212                 ret |= (Uint64)ch << 8*i;
213         }
214         
215         for( ; i < 7; i++ )
216                 ret |= 0x20 << (8*i);
217         
218         return ret;
219 }

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