sgcn.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2006 Ondrej Palkovsky
00003  * Copyright (c) 2008 Martin Decky
00004  * Copyright (c) 2008 Pavel Rimsky
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions
00009  * are met:
00010  *
00011  * - Redistributions of source code must retain the above copyright
00012  *   notice, this list of conditions and the following disclaimer.
00013  * - Redistributions in binary form must reproduce the above copyright
00014  *   notice, this list of conditions and the following disclaimer in the
00015  *   documentation and/or other materials provided with the distribution.
00016  * - The name of the author may not be used to endorse or promote products
00017  *   derived from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00020  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00021  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00022  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00023  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00024  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00025  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00026  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00028  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  */
00030 
00038 #include <async.h>
00039 #include <sysinfo.h>
00040 #include <as.h>
00041 #include <errno.h>
00042 #include <stdio.h>
00043 #include <ddi.h>
00044 
00045 #include "serial_console.h"
00046 #include "sgcn.h"
00047 
00048 #define WIDTH 80
00049 #define HEIGHT 24
00050 
00054 static uintptr_t sram_virt_addr;
00055 
00059 static uintptr_t sram_buffer_offset;
00060 
00065 typedef struct {
00067         char magic[4];
00068         
00070         char unused[24];
00071 
00073         uint32_t out_begin;
00074         
00076         uint32_t out_end;
00077         
00079         uint32_t out_rdptr;
00080         
00082         uint32_t out_wrptr;
00083 } __attribute__ ((packed)) sgcn_buffer_header_t;
00084 
00085 
00086 /*
00087  * Returns a pointer to the object of a given type which is placed at the given
00088  * offset from the console buffer beginning.
00089  */
00090 #define SGCN_BUFFER(type, offset) \
00091                 ((type *) (sram_virt_addr + sram_buffer_offset + (offset)))
00092 
00094 #define SGCN_BUFFER_HEADER      (SGCN_BUFFER(sgcn_buffer_header_t, 0))
00095 
00100 static void sgcn_putc(char c)
00101 {
00102         uint32_t begin = SGCN_BUFFER_HEADER->out_begin;
00103         uint32_t end = SGCN_BUFFER_HEADER->out_end;
00104         uint32_t size = end - begin;
00105         
00106         /* we need pointers to volatile variables */
00107         volatile char *buf_ptr = (volatile char *)
00108                 SGCN_BUFFER(char, SGCN_BUFFER_HEADER->out_wrptr);
00109         volatile uint32_t *out_wrptr_ptr = &(SGCN_BUFFER_HEADER->out_wrptr);
00110         volatile uint32_t *out_rdptr_ptr = &(SGCN_BUFFER_HEADER->out_rdptr);
00111 
00112         uint32_t new_wrptr = (((*out_wrptr_ptr) - begin + 1) % size) + begin;
00113         while (*out_rdptr_ptr == new_wrptr)
00114                 ;
00115         *buf_ptr = c;
00116         *out_wrptr_ptr = new_wrptr;
00117 }
00118 
00122 int sgcn_init(void)
00123 {
00124         sysarg_t sram_paddr;
00125         if (sysinfo_get_value("sram.address.physical", &sram_paddr) != EOK)
00126                 return -1;
00127         
00128         sysarg_t sram_size;
00129         if (sysinfo_get_value("sram.area.size", &sram_size) != EOK)
00130                 return -1;
00131         
00132         if (sysinfo_get_value("sram.buffer.offset", &sram_buffer_offset) != EOK)
00133                 sram_buffer_offset = 0;
00134         
00135         sram_virt_addr = (uintptr_t) as_get_mappable_page(sram_size);
00136         
00137         if (physmem_map((void *) sram_paddr, (void *) sram_virt_addr,
00138             sram_size / PAGE_SIZE, AS_AREA_READ | AS_AREA_WRITE) != 0)
00139                 return -1;
00140         
00141         serial_console_init(sgcn_putc, WIDTH, HEIGHT);
00142         
00143         async_set_client_connection(serial_client_connection);
00144         return 0;
00145 }
00146 

Generated on Thu Jun 2 07:45:49 2011 for HelenOS/USB by  doxygen 1.4.7