00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
00088
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
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