]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/IA32_flat_GCC_Galileo_Gen_2/Support_Files/galileo-support.c
commit 9f316c246baafa15c542a5aea81a94f26e3d6507
[freertos] / FreeRTOS / Demo / IA32_flat_GCC_Galileo_Gen_2 / Support_Files / galileo-support.c
1 /*--------------------------------------------------------------------\r
2  Copyright(c) 2015 Intel Corporation. All rights reserved.\r
3 \r
4  Redistribution and use in source and binary forms, with or without\r
5  modification, are permitted provided that the following conditions\r
6  are met:\r
7 \r
8  * Redistributions of source code must retain the above copyright\r
9  notice, this list of conditions and the following disclaimer.\r
10  * Redistributions in binary form must reproduce the above copyright\r
11  notice, this list of conditions and the following disclaimer in\r
12  the documentation and/or other materials provided with the\r
13  distribution.\r
14  * Neither the name of Intel Corporation nor the names of its\r
15  contributors may be used to endorse or promote products derived\r
16  from this software without specific prior written permission.\r
17 \r
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
19  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
20  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
21  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\r
22  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
23  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
24  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
25  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
26  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
27  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
28  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
29  --------------------------------------------------------------------*/\r
30 \r
31 /*-----------------------------------------------------------------------\r
32  * Any required includes\r
33  *------------------------------------------------------------------------\r
34  */\r
35 #include "multiboot.h"\r
36 #include "galileo_support.h"\r
37 \r
38 /*-----------------------------------------------------------------------\r
39  * Any required local definitions\r
40  *------------------------------------------------------------------------\r
41  */\r
42 #ifndef NULL\r
43         #define NULL (void *)0\r
44 #endif\r
45 \r
46 #define MUTEX_WAIT_TIME (( TickType_t ) 8 )\r
47 \r
48 /*-----------------------------------------------------------------------\r
49  * Function prototypes\r
50  *------------------------------------------------------------------------\r
51  */\r
52 extern void *memcpy( void *pvDest, const void *pvSource, unsigned long ulBytes );\r
53 \r
54 /*-----------------------------------------------------------------------\r
55  * Global variables\r
56  *------------------------------------------------------------------------\r
57  */\r
58 uint32_t bootinfo = 1UL;\r
59 uint32_t bootsign = 1UL;\r
60 \r
61 /*-----------------------------------------------------------------------\r
62  * Static variables\r
63  *------------------------------------------------------------------------\r
64  */\r
65 static uint32_t bGalileoSerialPortInitialized = FALSE;\r
66 static uint32_t uiLEDBlinkState = LED_OFF;\r
67 static uint16_t usIRQMask = 0xfffb;\r
68 static uint32_t UART_PCI_Base = 0UL;\r
69 static uint32_t UART_MMIO_Base = 0UL;\r
70 static SemaphoreHandle_t semPrintfGate = 0;\r
71 \r
72 /*------------------------------------------------------------------------\r
73  * GDT default entries (used in GDT setup code)\r
74  *------------------------------------------------------------------------\r
75  */\r
76 static struct sd gdt_default[NGDE] =\r
77 {\r
78         /*   sd_lolimit  sd_lobase   sd_midbase  sd_access   sd_hilim_fl sd_hibase */\r
79         /* 0th entry NULL */\r
80         {            0,          0,           0,         0,            0,        0, },\r
81         /* 1st, Kernel Code Segment */\r
82         {       0xffff,          0,           0,      0x9a,         0xcf,        0, },\r
83         /* 2nd, Kernel Data Segment */\r
84         {       0xffff,          0,           0,      0x92,         0xcf,        0, },\r
85         /* 3rd, Kernel Stack Segment */\r
86         {       0xffff,          0,           0,      0x92,         0xcf,        0, },\r
87         /* 4st, Boot Code Segment */\r
88         {       0xffff,          0,           0,      0x9a,         0xcf,        0, },\r
89         /* 5th, Code Segment for BIOS32 request */\r
90         {       0xffff,          0,           0,      0x9a,         0xcf,        0, },\r
91         /* 6th, Data Segment for BIOS32 request */\r
92         {       0xffff,          0,           0,      0x92,         0xcf,        0, },\r
93 };\r
94 \r
95 extern struct sd gdt[]; /* Global segment table (defined in startup.S) */\r
96 \r
97 /*------------------------------------------------------------------------\r
98  * Set segment registers (used in GDT setup code)\r
99  *------------------------------------------------------------------------\r
100  */\r
101 void setsegs()\r
102 {\r
103         extern int      __text_end;\r
104         struct sd       *psd;\r
105         uint32_t        np, ds_end;\r
106 \r
107         ds_end = 0xffffffff/PAGE_SIZE;          /* End page number */\r
108 \r
109         psd = &gdt_default[1];                          /* Kernel code segment */\r
110         np = ((int)&__text_end - 0 + PAGE_SIZE-1) / PAGE_SIZE;  /* Number of code pages */\r
111         psd->sd_lolimit = np;\r
112         psd->sd_hilim_fl = FLAGS_SETTINGS | ((np >> 16) & 0xff);\r
113 \r
114         psd = &gdt_default[2];                          /* Kernel data segment */\r
115         psd->sd_lolimit = ds_end;\r
116         psd->sd_hilim_fl = FLAGS_SETTINGS | ((ds_end >> 16) & 0xff);\r
117 \r
118         psd = &gdt_default[3];                          /* Kernel stack segment */\r
119         psd->sd_lolimit = ds_end;\r
120         psd->sd_hilim_fl = FLAGS_SETTINGS | ((ds_end >> 16) & 0xff);\r
121 \r
122         psd = &gdt_default[4];                          /* Boot code segment */\r
123         psd->sd_lolimit = ds_end;\r
124         psd->sd_hilim_fl = FLAGS_SETTINGS | ((ds_end >> 16) & 0xff);\r
125 \r
126         memcpy(gdt, gdt_default, sizeof(gdt_default));\r
127 }\r
128 /*-----------------------------------------------------------*/\r
129 \r
130 /*-----------------------------------------------------------------------\r
131   * Debug serial port display update functions\r
132   *------------------------------------------------------------------------\r
133   */\r
134  static void vCreatePrintfSemaphore( void )\r
135  {\r
136         if (semPrintfGate == 0)\r
137         {\r
138                 semPrintfGate = xSemaphoreCreateRecursiveMutex();\r
139                 vQueueAddToRegistry( ( QueueHandle_t ) semPrintfGate, "g_printf_Mutex" );\r
140         }\r
141  }\r
142  /*-----------------------------------------------------------*/\r
143 \r
144  void ClearScreen(void)\r
145  {\r
146         g_printf(ANSI_CLEAR_SB);\r
147         g_printf(ANSI_CLEAR_SCREEN);\r
148  }\r
149  /*-----------------------------------------------------------*/\r
150 \r
151  void MoveToScreenPosition(uint8_t row, uint8_t col)\r
152  {\r
153         g_printf("%c[%d;%dH", (char) 0x1B, row, col);\r
154  }\r
155  /*-----------------------------------------------------------*/\r
156 \r
157  void UngatedMoveToScreenPosition(uint8_t row, uint8_t col)\r
158  {\r
159         printf("%c[%d;%dH", (char) 0x1B, row, col);\r
160  }\r
161 /*-----------------------------------------------------------*/\r
162 \r
163  void SetScreenColor(const char *color)\r
164  {\r
165          g_printf("%s", color);\r
166  }\r
167  /*-----------------------------------------------------------*/\r
168 \r
169  void g_printf(const char *format, ...)\r
170  {\r
171 \r
172          if (semPrintfGate == 0)\r
173                  vCreatePrintfSemaphore();\r
174 \r
175          if (xSemaphoreTakeRecursive(semPrintfGate, MUTEX_WAIT_TIME))\r
176          {\r
177              va_list arguments;\r
178              va_start(arguments,format);\r
179              print(0, format, arguments);\r
180              xSemaphoreGiveRecursive(semPrintfGate);\r
181          }\r
182  }\r
183  /*-----------------------------------------------------------*/\r
184 \r
185  void g_printf_rcc(uint8_t row, uint8_t col, const char *color, const char *format, ...)\r
186  {\r
187          if (semPrintfGate == 0)\r
188                  vCreatePrintfSemaphore();\r
189 \r
190          if (xSemaphoreTakeRecursive(semPrintfGate, MUTEX_WAIT_TIME ))\r
191          {\r
192                  UngatedMoveToScreenPosition(row, col);\r
193                  printf("%s",color);\r
194              va_list arguments;\r
195              va_start(arguments,format);\r
196              print(0, format, arguments);\r
197                  xSemaphoreGiveRecursive(semPrintfGate);\r
198          }\r
199 }\r
200  /*-----------------------------------------------------------*/\r
201 \r
202  void vPrintBanner( void )\r
203  {\r
204          if (bGalileoSerialPortInitialized)\r
205          {\r
206                 /* Print an RTOSDemo Loaded message */\r
207                 ClearScreen();\r
208                 g_printf_rcc(1, 2, DEFAULT_BANNER_COLOR,\r
209                 "%c[1mHELLO from the multiboot compliant FreeRTOS kernel!%c[0m",\r
210                 (char) 0x1B, (char) 0x1B );\r
211                 printf(ANSI_HIDE_CURSOR);\r
212          }\r
213  }\r
214  /*-----------------------------------------------------------*/\r
215 \r
216 /*------------------------------------------------------------------------\r
217  * Multiboot support (show parameters passed back from GRUB)\r
218  *------------------------------------------------------------------------\r
219  */\r
220 void show_kernel_parameters( unsigned long magic, unsigned long addr )\r
221 {\r
222         /* Set to 0 to quiet display. */\r
223         uint8_t print_values = 1;\r
224 \r
225         /* Initialise serial port if necessary. */\r
226         vInitializeGalileoSerialPort(DEBUG_SERIAL_PORT);\r
227 \r
228         if (print_values != 0)\r
229         {\r
230                 ClearScreen();\r
231                 g_printf(DEFAULT_SCREEN_COLOR);\r
232                 MoveToScreenPosition(1, 2);\r
233                 g_printf ("\n\r ...MULTIBOOT VALUES RETURNED FROM GRUB...\n\n\r");\r
234                 g_printf(ANSI_COLOR_WHITE);\r
235         }\r
236 \r
237         if (magic != MULTIBOOT_BOOTLOADER_MAGIC)\r
238         {\r
239                 printf(ANSI_COLOR_RED);\r
240                 if (print_values != 0)\r
241                         g_printf (" Invalid magic number returned: 0x%08x\n\r", (unsigned) magic);\r
242                 g_printf(ANSI_COLOR_RESET);\r
243         }\r
244         else\r
245         {\r
246            multiboot_info_t *mbi;\r
247            /* Set MBI to the address of the Multiboot information structure. */\r
248            mbi = (multiboot_info_t *) addr;\r
249 \r
250            /* Is the command line passed? */\r
251            if (CHECK_FLAG (mbi->flags, 2))\r
252                         if (print_values != 0)\r
253                                 g_printf (" cmdline = %s\n\r", (char *) mbi->cmdline);\r
254 \r
255            /* Print out the flags. */\r
256            if (print_values != 0)\r
257                    g_printf (" flags = 0x%08x\n\r", (unsigned) mbi->flags);\r
258 \r
259            /* Are mem_* valid? */\r
260            if (CHECK_FLAG (mbi->flags, 0))\r
261                         if (print_values != 0)\r
262                                 g_printf (" mem_lower = %u KB, mem_upper = %u KB\n\r",\r
263                                 (unsigned) mbi->mem_lower, (unsigned) mbi->mem_upper);\r
264 \r
265            /* Is boot_device valid? */\r
266            if (CHECK_FLAG (mbi->flags, 1))\r
267                         if (print_values != 0)\r
268                                 g_printf (" boot_device = 0x%08x\n\r", (unsigned) mbi->boot_device);\r
269 \r
270            if (CHECK_FLAG (mbi->flags, 3))\r
271            {\r
272                    module_t *mod;\r
273                    int i;\r
274                    if (print_values != 0)\r
275                            g_printf (" mods_count = %d, mods_addr = 0x%08x\n\r",\r
276                                 (int) mbi->mods_count, (int) mbi->mods_addr);\r
277                    for (i = 0, mod = (module_t *) mbi->mods_addr;\r
278                                 i < (int)mbi->mods_count;\r
279                             i++, mod++)\r
280                    {\r
281                                 if (print_values != 0)\r
282                                         g_printf ("    mod_start = 0x%08x, mod_end = 0x%08x, cmdline = %s\n\r",\r
283                                         (unsigned) mod->mod_start,\r
284                                         (unsigned) mod->mod_end,\r
285                                         (char *) mod->string);\r
286                    }\r
287            }\r
288 \r
289        /* Bits 4 and 5 are mutually exclusive! */\r
290        if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5))\r
291        {\r
292            if (print_values != 0)\r
293                    g_printf (" Both bits 4 and 5 are set.\n\r");\r
294        }\r
295        else\r
296        {\r
297            /* Is the symbol table of a.out valid? */\r
298            if (CHECK_FLAG (mbi->flags, 4))\r
299            {\r
300                    aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym);\r
301                    if (print_values != 0)\r
302                            g_printf (" multiboot_aout_symbol_table: tabsize = 0x%08x, "\r
303                             "strsize = 0x%08x, addr = 0x%08x\n\r",\r
304                                 (unsigned) multiboot_aout_sym->tabsize,\r
305                                 (unsigned) multiboot_aout_sym->strsize,\r
306                                 (unsigned) multiboot_aout_sym->addr);\r
307            }\r
308 \r
309            /* Is the section header table of ELF valid? */\r
310            if (CHECK_FLAG (mbi->flags, 5))\r
311            {\r
312                    elf_section_header_table_t *multiboot_elf_sec = &(mbi->u.elf_sec);\r
313                    if (print_values != 0)\r
314                             g_printf (" multiboot_elf_sec: num = %u, size = 0x%08x,"\r
315                                 " addr = 0x%08x, shndx = 0x%04x\n\r",\r
316                                 (unsigned) multiboot_elf_sec->num, (unsigned) multiboot_elf_sec->size,\r
317                                 (unsigned) multiboot_elf_sec->addr, (unsigned) multiboot_elf_sec->shndx);\r
318            }\r
319 \r
320            /* Are mmap_* valid? */\r
321            if (CHECK_FLAG (mbi->flags, 6))\r
322            {\r
323                    memory_map_t *mmap;\r
324                    if (print_values != 0)\r
325                            g_printf (" mmap_addr = 0x%08x, mmap_length = 0x%08x\n\r",\r
326                            (unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length);\r
327                for (mmap = (memory_map_t *) mbi->mmap_addr;\r
328                     (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length;\r
329                     mmap = (memory_map_t *) ((unsigned long) mmap\r
330                     + mmap->size + sizeof (mmap->size)))\r
331                {\r
332                    if (print_values != 0)\r
333                            g_printf ("    size = 0x%08x, base_addr = 0x%04x%04x,"\r
334                                    " length = 0x%04x%04x, type = 0x%04x\n\r",\r
335                                    (unsigned) mmap->size,\r
336                                    (uint16_t) mmap->base_addr_high,\r
337                                    (uint16_t)mmap->base_addr_low,\r
338                                    (uint16_t)mmap->length_high,\r
339                                    (uint16_t)mmap->length_low,\r
340                                    (unsigned) mmap->type);\r
341                }\r
342            }\r
343 \r
344            if (print_values != 0)\r
345            {\r
346                    g_printf(DEFAULT_SCREEN_COLOR);\r
347                    g_printf ("\n\r Press any key to continue.\n\r");\r
348                            while (ucGalileoGetchar() == 0)\r
349                            {\r
350                                         __asm volatile( "NOP" );\r
351                            }\r
352            }\r
353            main();\r
354        }\r
355         }\r
356 }\r
357 /*-----------------------------------------------------------*/\r
358 \r
359 /*------------------------------------------------------------------------\r
360  * 8259 PIC initialization and support code\r
361  *------------------------------------------------------------------------\r
362  */\r
363  void vInitialize8259Chips(void)\r
364  {\r
365         /* Set interrupt mask */\r
366         uint16_t IRQMask = 0xffff;\r
367         outb(IMR1, (uint8_t) (IRQMask & 0xff));\r
368         outb(IMR2, (uint8_t) ((IRQMask >> 8) & 0xff));\r
369 \r
370         /* Initialise the 8259A interrupt controllers */\r
371 \r
372         /* Master device */\r
373         outb(ICU1, 0x11);       /* ICW1: icw4 needed            */\r
374         outb(ICU1+1, 0x20);     /* ICW2: base ivec 32           */\r
375         outb(ICU1+1, 0x4);      /* ICW3: cascade on irq2        */\r
376         outb(ICU1+1, 0x1);      /* ICW4: buf. master, 808x mode */\r
377 \r
378         /* Slave device */\r
379         outb(ICU2, 0x11);       /* ICW1: icw4 needed            */\r
380         outb(ICU2+1, 0x28);     /* ICW2: base ivec 40           */\r
381         outb(ICU2+1, 0x2);      /* ICW3: slave on irq2          */\r
382         outb(ICU2+1, 0xb);      /* ICW4: buf. slave, 808x mode  */\r
383 \r
384         vMicroSecondDelay (100);\r
385 \r
386         /* always read ISR */\r
387         outb(ICU1, 0xb);        /* OCW3: set ISR on read        */\r
388         outb(ICU2, 0xb);        /* OCW3: set ISR on read        */\r
389 \r
390         /* Set interrupt mask - leave bit 2 enabled for IC cascade */\r
391         IRQMask = 0xfffb;\r
392         outb(IMR1, (uint8_t) (IRQMask & 0xff));\r
393         outb(IMR2, (uint8_t) ((IRQMask >> 8) & 0xff));\r
394  }\r
395  /*-----------------------------------------------------------*/\r
396 \r
397  void vClearIRQMask(uint8_t IRQNumber)\r
398  {\r
399          if( ( IRQNumber > 31 ) && ( IRQNumber < 48 ) )\r
400          {\r
401                 usIRQMask &= ~( 1 << (IRQNumber - 32 ) );\r
402                 usIRQMask &= 0xfffb;    // bit 2 is slave cascade\r
403                 usIRQMask |= 0x0200;    // bit 14 is reserved\r
404                 outb(IMR1, (uint8_t) (usIRQMask & 0xff));\r
405                 outb(IMR2, (uint8_t) ((usIRQMask >> 8) & 0xff));\r
406          }\r
407  }\r
408  /*-----------------------------------------------------------*/\r
409 \r
410  void vSetIRQMask(uint8_t IRQNumber)\r
411  {\r
412          if( ( IRQNumber > 31 ) && ( IRQNumber < 48 ) )\r
413          {\r
414                 usIRQMask |= ( 1 << (IRQNumber - 32 ) );\r
415                 usIRQMask &= 0xfffb;    // bit 2 is slave cascade\r
416                 usIRQMask |= 0x0200;    // bit 14 is reserved\r
417                 outb(IMR1, (uint8_t) (usIRQMask & 0xff));\r
418                 outb(IMR2, (uint8_t) ((usIRQMask >> 8) & 0xff));\r
419          }\r
420  }\r
421  /*-----------------------------------------------------------*/\r
422 \r
423  /*-----------------------------------------------------------------------\r
424   * 82C54 PIT (programmable interval timer) initialization\r
425   *------------------------------------------------------------------------\r
426   */\r
427  void vInitializePIT(void)\r
428  {\r
429         /* Set the hardware clock: timer 0, 16-bit counter, rate                */\r
430         /* generator mode, and counter runs in binary                               */\r
431         outb(CLKCNTL, 0x34);\r
432 \r
433         /* Set the clock rate to 1.193 Mhz, this is 1 ms interrupt rate         */\r
434         uint16_t intrate = 1193;\r
435         /* Must write LSB first, then MSB                                       */\r
436         outb(CLKBASE, (char) (intrate & 0xff));\r
437         outb(CLKBASE, (char) ((intrate >> 8) & 0xff));\r
438  }\r
439  /*-----------------------------------------------------------*/\r
440 \r
441  /*-----------------------------------------------------------------------\r
442   * LED support for main_blinky()\r
443   *------------------------------------------------------------------------\r
444   */\r
445  uint32_t ulBlinkLED(void)\r
446  {\r
447          if( uiLEDBlinkState == LED_OFF )\r
448          {\r
449                  uiLEDBlinkState = LED_ON;\r
450          }\r
451          else\r
452          {\r
453                  uiLEDBlinkState = LED_OFF;\r
454          }\r
455 \r
456          vGalileoBlinkLEDUsingLegacyGPIO(uiLEDBlinkState);\r
457 \r
458          return uiLEDBlinkState;\r
459  }\r
460  /*-----------------------------------------------------------*/\r
461 \r
462  /*-----------------------------------------------------------------------\r
463   * Serial port initialization code\r
464   *------------------------------------------------------------------------\r
465   */\r
466  static void vInitializeGalileoUART(uint32_t portnumber)\r
467  {\r
468         volatile uint8_t divisor = 24;\r
469         volatile uint8_t output_data = 0x3 & 0xFB & 0xF7;\r
470         volatile uint8_t input_data = 0;\r
471         volatile uint8_t lcr = 0;\r
472 \r
473         if (portnumber == DEBUG_SERIAL_PORT)\r
474                 UART_PCI_Base = MMIO_PCI_ADDRESS(0, 20, 5, 0);\r
475         else\r
476                 UART_PCI_Base = MMIO_PCI_ADDRESS(0, 20, 1, 0);\r
477 \r
478         uint32_t base = mem_read(UART_PCI_Base, 0x10, 4);\r
479         UART_MMIO_Base = base;\r
480 \r
481         mem_write(base, R_UART_SCR, 1, 0xAB);\r
482 \r
483         mem_write(base, R_UART_LCR, 1, output_data | B_UARY_LCR_DLAB);\r
484 \r
485         mem_write(base, R_UART_BAUD_HIGH, 1, (uint8_t)(divisor >> 8));\r
486         mem_write(base, R_UART_BAUD_LOW, 1, (uint8_t)(divisor & 0xff));\r
487 \r
488         mem_write(base, R_UART_LCR, 1, output_data);\r
489 \r
490         mem_write(base, R_UART_FCR, 1, (uint8_t)(B_UARY_FCR_TRFIFIE |\r
491                 B_UARY_FCR_RESETRF | B_UARY_FCR_RESETTF | 0x30));\r
492 \r
493         input_data = mem_read(base, R_UART_MCR, 1);\r
494         input_data |= BIT1;\r
495         input_data &= ~BIT5;\r
496         mem_write(base, R_UART_MCR, 1, input_data);\r
497 \r
498         lcr = mem_read(base, R_UART_LCR, 1);\r
499         mem_write(base, R_UART_LCR, 1, (uint8_t) (lcr & ~B_UARY_LCR_DLAB));\r
500 \r
501         mem_write(base, R_UART_IER, 1, 0);\r
502  }\r
503  /*-----------------------------------------------------------*/\r
504 \r
505  void vInitializeGalileoSerialPort(uint32_t portnumber)\r
506  {\r
507         if( bGalileoSerialPortInitialized == FALSE )\r
508         {\r
509                 /* Initialise for 115200, 8, 1, none and no handshaking */\r
510                 vInitializeGalileoUART(portnumber);\r
511                 bGalileoSerialPortInitialized = TRUE;\r
512         }\r
513  }\r
514  /*-----------------------------------------------------------*/\r
515 \r
516  /*-----------------------------------------------------------------------\r
517   * Serial port support functions\r
518   *------------------------------------------------------------------------\r
519   */\r
520  void vGalileoPrintc(char c)\r
521  {\r
522         if (bGalileoSerialPortInitialized)\r
523         {\r
524                 while((mem_read(UART_MMIO_Base, R_UART_LSR, 1) & B_UART_LSR_TXRDY) == 0);\r
525                 mem_write(UART_MMIO_Base, R_UART_BAUD_THR, 1, c);\r
526         }\r
527  }\r
528  /*-----------------------------------------------------------*/\r
529 \r
530  uint8_t ucGalileoGetchar()\r
531  {\r
532         uint8_t c = 0;\r
533         if (bGalileoSerialPortInitialized)\r
534         {\r
535                 if((mem_read(UART_MMIO_Base, R_UART_LSR, 1) & B_UART_LSR_RXRDY) != 0)\r
536                         c  = mem_read(UART_MMIO_Base, R_UART_BAUD_THR, 1);\r
537         }\r
538           return c;\r
539  }\r
540  /*-----------------------------------------------------------*/\r
541 \r
542  void vGalileoPuts(const char *string)\r
543  {\r
544         if (bGalileoSerialPortInitialized)\r
545         {\r
546             while(*string)\r
547                 vGalileoPrintc(*string++);\r
548         }\r
549  }\r
550  /*-----------------------------------------------------------*/\r