Changeset a71c158 in mainline
- Timestamp:
- 2009-08-21T14:12:45Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0e6dce8, b50b5af2, e5792d1
- Parents:
- 90c8b8d
- Location:
- kernel
- Files:
-
- 32 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/amd64/src/amd64.c
r90c8b8d ra71c158 151 151 i8254_init(); 152 152 153 #if (defined(CONFIG_FB) || defined(CONFIG_EGA)) 154 bool vesa = false; 155 #endif 156 153 157 #ifdef CONFIG_FB 154 if (vesa_present()) 155 vesa_init(); 156 else 157 #endif 158 vesa = vesa_init(); 159 #endif 160 158 161 #ifdef CONFIG_EGA 159 ega_init(EGA_BASE, EGA_VIDEORAM); /* video */ 160 #else 161 {} 162 if (!vesa) { 163 outdev_t *egadev = ega_init(EGA_BASE, EGA_VIDEORAM); 164 if (egadev) 165 stdout_wire(egadev); 166 } 162 167 #endif 163 168 … … 249 254 } 250 255 251 /** Acquire console back for kernel252 *253 */254 void arch_grab_console(void)255 {256 #ifdef CONFIG_FB257 if (vesa_present())258 vesa_redraw();259 else260 #endif261 #ifdef CONFIG_EGA262 ega_redraw();263 #else264 {}265 #endif266 }267 268 /** Return console to userspace269 *270 */271 void arch_release_console(void)272 {273 }274 275 256 /** Construct function pointer 276 257 * -
kernel/arch/arm32/include/mach/integratorcp/integratorcp.h
r90c8b8d ra71c158 98 98 99 99 extern void icp_init(void); 100 extern void icp_fb_init(void);101 100 extern void icp_output_init(void); 102 101 extern void icp_input_init(void); 103 extern void icp_release_console(void);104 extern void icp_grab_console(void);105 102 extern void icp_timer_irq_start(void); 106 103 extern void icp_cpu_halt(void); 107 104 extern void icp_irq_exception(int exc_no, istate_t *istate); 108 105 extern uintptr_t icp_get_memory_size(void); 109 extern uintptr_t icp_get_fb_address(void);110 extern void icp_fb_init(void);111 106 extern void icp_frame_init(void); 112 107 -
kernel/arch/arm32/include/mach/testarm/testarm.h
r90c8b8d ra71c158 68 68 69 69 extern void gxemul_init(void); 70 extern void gxemul_fb_init(void);71 70 extern void gxemul_output_init(void); 72 71 extern void gxemul_input_init(void); 73 extern void gxemul_release_console(void);74 extern void gxemul_grab_console(void);75 72 extern void gxemul_timer_irq_start(void); 76 73 extern void gxemul_cpu_halt(void); 77 74 extern void gxemul_irq_exception(int exc_no, istate_t *istate); 78 75 extern uintptr_t gxemul_get_memory_size(void); 79 extern uintptr_t gxemul_get_fb_address(void);80 extern void gxemul_fb_init(void);81 76 extern void gxemul_frame_init(void); 82 77 -
kernel/arch/arm32/include/machine_func.h
r90c8b8d ra71c158 49 49 50 50 struct arm_machine_ops { 51 void (*machine_grab_console)(void);52 void (*machine_release_console)(void);53 51 void (*machine_init)(void); 54 52 void (*machine_timer_irq_start)(void); 55 53 void (*machine_cpu_halt)(void); 56 54 uintptr_t (*machine_get_memory_size)(void); 57 void (*machine_fb_init)(void);58 55 void (*machine_irq_exception)(int, istate_t*); 59 uintptr_t (*machine_get_fb_address)(void);60 56 void (*machine_frame_init)(void); 61 57 void (*machine_output_init)(void); … … 64 60 65 61 extern struct arm_machine_ops machine_ops; 66 67 68 /** Acquire console back for kernel. */69 extern void machine_grab_console(void);70 71 /** Return console to userspace. */72 extern void machine_release_console(void);73 62 74 63 … … 91 80 extern uintptr_t machine_get_memory_size(void); 92 81 93 /** Initializes the Frame Buffer94 *95 */96 extern void machine_fb_init(void);97 98 82 99 83 /** Interrupt exception handler. … … 104 88 extern void machine_irq_exception(int exc_no, istate_t *istate); 105 89 106 107 /** Returns address of framebuffer device.108 *109 * @return Address of framebuffer device.110 */111 extern uintptr_t machine_get_fb_address(void);112 90 113 91 /* -
kernel/arch/arm32/src/arm32.c
r90c8b8d ra71c158 89 89 interrupt_init(); 90 90 91 #ifdef CONFIG_FB92 machine_fb_init();93 #else94 #ifdef CONFIG_ARM_PRN95 91 machine_output_init(); 96 #endif /* CONFIG_ARM_PRN */97 #endif /* CONFIG_FB */98 92 } 99 93 … … 182 176 } 183 177 184 /** Acquire console back for kernel. */185 void arch_grab_console(void)186 {187 machine_grab_console();188 #ifdef CONFIG_FB189 fb_redraw();190 #endif191 }192 193 /** Return console to userspace. */194 void arch_release_console(void)195 {196 machine_release_console();197 }198 199 178 /** @} 200 179 */ -
kernel/arch/arm32/src/mach/integratorcp/integratorcp.c
r90c8b8d ra71c158 57 57 static irq_t icp_timer_irq; 58 58 struct arm_machine_ops machine_ops = { 59 MACHINE_GENFUNC,60 MACHINE_GENFUNC,61 59 icp_init, 62 60 icp_timer_irq_start, 63 61 icp_cpu_halt, 64 62 icp_get_memory_size, 65 icp_fb_init,66 63 icp_irq_exception, 67 icp_get_fb_address,68 64 icp_frame_init, 69 65 icp_output_init, … … 128 124 } 129 125 130 /** Initializes the icp frame buffer */131 void icp_fb_init(void)132 {133 fb_properties_t prop = {134 .addr = 0,135 .offset = 0,136 .x = 640,137 .y = 480,138 .scan = 2560,139 .visual = VISUAL_BGR_0_8_8_8,140 };141 prop.addr = icp_get_fb_address();142 fb_init(&prop);143 fb_parea.pbase = ICP_FB;144 fb_parea.frames = 300;145 ddi_parea_register(&fb_parea);146 }147 148 126 /** Initializes icp_hw_map. */ 149 127 void icp_init(void) … … 172 150 } 173 151 174 175 /** Acquire console back for kernel. */176 void icp_grab_console(void)177 {178 }179 180 /** Return console to userspace. */181 void icp_release_console(void)182 {183 }184 185 152 /** Starts icp Real Time Clock device, which asserts regular interrupts. 186 * 153 * 187 154 * @param frequency Interrupts frequency (0 disables RTC). 188 155 */ … … 296 263 } 297 264 298 /** Returns address of framebuffer device. 299 * 300 * @return Address of framebuffer device. 301 */ 302 uintptr_t icp_get_fb_address(void) 303 { 265 /* 266 * Integrator specific frame initialization 267 */ 268 void 269 icp_frame_init(void) 270 { 271 frame_mark_unavailable(ICP_FB_FRAME, ICP_FB_NUM_FRAME); 272 frame_mark_unavailable(0, 256); 273 } 274 275 void icp_output_init(void) 276 { 277 #ifdef CONFIG_FB 304 278 if (!vga_init) { 305 279 icp_vga_init(); 306 280 vga_init = true; 307 281 } 308 return (uintptr_t) ICP_FB; 309 } 310 311 /* 312 * Integrator specific frame initialization 313 */ 314 void 315 icp_frame_init(void) 316 { 317 frame_mark_unavailable(ICP_FB_FRAME, ICP_FB_NUM_FRAME); 318 frame_mark_unavailable(0, 256); 319 } 320 321 void icp_output_init(void) 322 { 282 283 fb_properties_t prop = { 284 .addr = ICP_FB, 285 .offset = 0, 286 .x = 640, 287 .y = 480, 288 .scan = 2560, 289 .visual = VISUAL_BGR_0_8_8_8, 290 }; 291 292 outdev_t *fbdev = fb_init(&prop); 293 if (fbdev) { 294 stdout_wire(fbdev); 295 fb_parea.pbase = ICP_FB; 296 fb_parea.frames = 300; 297 ddi_parea_register(&fb_parea); 298 } 299 #endif 323 300 } 324 301 -
kernel/arch/arm32/src/mach/testarm/testarm.c
r90c8b8d ra71c158 57 57 58 58 struct arm_machine_ops machine_ops = { 59 MACHINE_GENFUNC,60 MACHINE_GENFUNC,61 59 gxemul_init, 62 60 gxemul_timer_irq_start, 63 61 gxemul_cpu_halt, 64 62 gxemul_get_memory_size, 65 gxemul_fb_init,66 63 gxemul_irq_exception, 67 gxemul_get_fb_address,68 64 gxemul_frame_init, 69 65 gxemul_output_init, … … 78 74 } 79 75 80 void gxemul_fb_init(void) 81 { 76 void gxemul_output_init(void) 77 { 78 #ifdef CONFIG_FB 82 79 fb_properties_t prop = { 83 80 .addr = GXEMUL_FB_ADDRESS, … … 88 85 .visual = VISUAL_RGB_8_8_8, 89 86 }; 90 fb_init(&prop); 91 } 92 93 void gxemul_output_init(void) 94 { 95 dsrlnout_init((ioport8_t *) gxemul_kbd); 87 88 outdev_t *fbdev = fb_init(&prop); 89 if (fbdev) 90 stdout_wire(fbdev); 91 #endif 92 93 #ifdef CONFIG_ARM_PRN 94 outdev_t *dsrlndev = dsrlnout_init((ioport8_t *) gxemul_kbd); 95 if (dsrlndev) 96 stdout_wire(dsrlndev); 97 #endif 96 98 } 97 99 … … 233 235 } 234 236 235 uintptr_t gxemul_get_fb_address()236 {237 return ((uintptr_t)GXEMUL_FB_ADDRESS);238 }239 240 241 237 /** @} 242 238 */ -
kernel/arch/arm32/src/machine_func.c
r90c8b8d ra71c158 41 41 42 42 43 /** Acquire console back for kernel. */44 void machine_grab_console(void)45 {46 (machine_ops.machine_grab_console)();47 }48 49 /** Return console to userspace. */50 void machine_release_console(void)51 {52 (machine_ops.machine_release_console)();53 }54 55 56 43 /** Maps HW devices to the kernel address space using #hw_map. */ 57 44 void machine_init(void) … … 84 71 } 85 72 86 /** Initializes the Frame Buffer87 *88 */89 void machine_fb_init(void)90 {91 (machine_ops.machine_fb_init)();92 }93 94 95 73 /** Interrupt exception handler. 96 74 * … … 103 81 } 104 82 105 106 /** Returns address of framebuffer device.107 *108 * @return Address of framebuffer device.109 */110 uintptr_t machine_get_fb_address(void)111 {112 return (machine_ops.machine_get_fb_address)();113 }114 83 115 84 /* -
kernel/arch/ia32/include/drivers/vesa.h
r90c8b8d ra71c158 36 36 #define KERN_ia32_VESA_H_ 37 37 38 extern int vesa_present(void); 39 extern void vesa_redraw(void); 40 extern voidvesa_init(void);38 #include <arch/types.h> 39 40 extern bool vesa_init(void); 41 41 42 42 #endif -
kernel/arch/ia32/src/drivers/vesa.c
r90c8b8d ra71c158 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 40 40 #include <genarch/fb/visuals.h> 41 41 #include <arch/drivers/vesa.h> 42 #include <console/chardev.h> 43 #include <console/console.h> 42 44 #include <putchar.h> 43 45 #include <mm/page.h> … … 66 68 uint8_t vesa_blue_pos; 67 69 68 int vesa_present(void)70 bool vesa_init(void) 69 71 { 70 if ((vesa_width != 0xffff) && (vesa_height != 0xffff))71 return true;72 if ((vesa_width == 0xffff) || (vesa_height == 0xffff)) 73 return false; 72 74 73 return false; 74 } 75 76 void vesa_init(void) 77 { 78 unsigned int visual; 75 visual_t visual; 79 76 80 77 switch (vesa_bpp) { … … 97 94 break; 98 95 default: 99 panic("Unsupported bits per pixel."); 96 LOG("Unsupported bits per pixel."); 97 return false; 100 98 } 101 99 … … 108 106 .visual = visual, 109 107 }; 110 fb_init(&vesa_props); 111 } 112 113 void vesa_redraw(void) 114 { 115 fb_redraw(); 108 109 outdev_t *fbdev = fb_init(&vesa_props); 110 if (!fbdev) 111 return false; 112 113 stdout_wire(fbdev); 114 return true; 116 115 } 117 116 -
kernel/arch/ia32/src/ia32.c
r90c8b8d ra71c158 112 112 i8254_init(); 113 113 114 #if (defined(CONFIG_FB) || defined(CONFIG_EGA)) 115 bool vesa = false; 116 #endif 117 114 118 #ifdef CONFIG_FB 115 if (vesa_present()) 116 vesa_init(); 117 else 118 #endif 119 vesa = vesa_init(); 120 #endif 121 119 122 #ifdef CONFIG_EGA 120 ega_init(EGA_BASE, EGA_VIDEORAM); /* video */ 121 #else 122 {} 123 if (!vesa) { 124 outdev_t *egadev = ega_init(EGA_BASE, EGA_VIDEORAM); 125 if (egadev) 126 stdout_wire(egadev); 127 } 123 128 #endif 124 129 … … 201 206 THREAD->arch.tls = addr; 202 207 set_tls_desc(addr); 203 208 204 209 return 0; 205 }206 207 /** Acquire console back for kernel208 *209 */210 void arch_grab_console(void)211 {212 #ifdef CONFIG_FB213 if (vesa_present())214 vesa_redraw();215 else216 #endif217 #ifdef CONFIG_EGA218 ega_redraw();219 #else220 {}221 #endif222 }223 224 /** Return console to userspace225 *226 */227 void arch_release_console(void)228 {229 210 } 230 211 -
kernel/arch/ia64/include/drivers/ski.h
r90c8b8d ra71c158 44 44 } ski_instance_t; 45 45 46 extern voidskiout_init(void);46 extern outdev_t *skiout_init(void); 47 47 48 48 extern ski_instance_t *skiin_init(void); 49 49 extern void skiin_wire(ski_instance_t *, indev_t *); 50 extern void ski_kbd_grab(void);51 extern void ski_kbd_release(void);52 50 53 51 #endif -
kernel/arch/ia64/src/drivers/ski.c
r90c8b8d ra71c158 47 47 enum { 48 48 /** Interval between polling in microseconds */ 49 POLL_INTERVAL = 50 49 POLL_INTERVAL = 10000, /* 0.01 s */ 50 51 51 /** Max. number of characters to pull out at a time */ 52 POLL_LIMIT =30,53 54 SKI_INIT_CONSOLE 55 SKI_GETCHAR 56 SKI_PUTCHAR 52 POLL_LIMIT = 30, 53 54 SKI_INIT_CONSOLE = 20, 55 SKI_GETCHAR = 21, 56 SKI_PUTCHAR = 31 57 57 }; 58 58 59 59 static void ski_putchar(outdev_t *, const wchar_t, bool); 60 60 61 static outdev_operations_t skiout_ops = { 62 .write = ski_putchar 61 static outdev_operations_t skidev_ops = { 62 .write = ski_putchar, 63 .redraw = NULL 63 64 }; 64 65 65 static outdev_t skiout; /**< Ski output device. */ 66 static bool initialized = false; 67 static bool kbd_disabled = false; 66 static ski_instance_t *instance = NULL; 67 68 /** Ask debug console if a key was pressed. 69 * 70 * Use SSC (Simulator System Call) to 71 * get character from debug console. 72 * 73 * This call is non-blocking. 74 * 75 * @return ASCII code of pressed key or 0 if no key pressed. 76 * 77 */ 78 static wchar_t ski_getchar(void) 79 { 80 uint64_t ch; 81 82 asm volatile ( 83 "mov r15 = %1\n" 84 "break 0x80000;;\n" /* modifies r8 */ 85 "mov %0 = r8;;\n" 86 87 : "=r" (ch) 88 : "i" (SKI_GETCHAR) 89 : "r15", "r8" 90 ); 91 92 return (wchar_t) ch; 93 } 94 95 /** Ask keyboard if a key was pressed. 96 * 97 * If so, it will repeat and pull up to POLL_LIMIT characters. 98 */ 99 static void poll_keyboard(ski_instance_t *instance) 100 { 101 if (silent) 102 return; 103 104 int count = POLL_LIMIT; 105 106 while (count > 0) { 107 wchar_t ch = ski_getchar(); 108 109 if (ch == '\0') 110 break; 111 112 indev_push_character(instance->srlnin, ch); 113 --count; 114 } 115 } 116 117 /** Kernel thread for polling keyboard. */ 118 static void kskipoll(void *arg) 119 { 120 ski_instance_t *instance = (ski_instance_t *) arg; 121 122 while (true) { 123 if (!silent) 124 poll_keyboard(instance); 125 126 thread_usleep(POLL_INTERVAL); 127 } 128 } 68 129 69 130 /** Initialize debug console … … 75 136 static void ski_init(void) 76 137 { 77 if (in itialized)138 if (instance) 78 139 return; 79 140 … … 86 147 ); 87 148 88 initialized = true; 149 instance = malloc(sizeof(ski_instance_t), FRAME_ATOMIC); 150 151 if (instance) { 152 instance->thread = thread_create(kskipoll, instance, TASK, 0, 153 "kskipoll", true); 154 155 if (!instance->thread) { 156 free(instance); 157 instance = NULL; 158 return; 159 } 160 161 instance->srlnin = NULL; 162 } 89 163 } 90 164 … … 124 198 } 125 199 126 voidskiout_init(void)200 outdev_t *skiout_init(void) 127 201 { 128 202 ski_init(); 129 130 outdev_initialize("skiout", &skiout, &skiout_ops); 131 stdout_wire(&skiout); 132 133 sysinfo_set_item_val("fb", NULL, false); 134 } 135 136 /** Ask debug console if a key was pressed. 137 * 138 * Use SSC (Simulator System Call) to 139 * get character from debug console. 140 * 141 * This call is non-blocking. 142 * 143 * @return ASCII code of pressed key or 0 if no key pressed. 144 * 145 */ 146 static wchar_t ski_getchar(void) 147 { 148 uint64_t ch; 149 150 asm volatile ( 151 "mov r15 = %1\n" 152 "break 0x80000;;\n" /* modifies r8 */ 153 "mov %0 = r8;;\n" 154 155 : "=r" (ch) 156 : "i" (SKI_GETCHAR) 157 : "r15", "r8" 158 ); 159 160 return (wchar_t) ch; 161 } 162 163 /** Ask keyboard if a key was pressed. 164 * 165 * If so, it will repeat and pull up to POLL_LIMIT characters. 166 */ 167 static void poll_keyboard(ski_instance_t *instance) 168 { 169 wchar_t ch; 170 int count; 171 172 if (kbd_disabled) 173 return; 174 175 count = POLL_LIMIT; 176 177 while (count > 0) { 178 ch = ski_getchar(); 179 180 if (ch == '\0') 181 break; 182 183 indev_push_character(instance->srlnin, ch); 184 --count; 185 } 186 } 187 188 /** Kernel thread for polling keyboard. */ 189 static void kskipoll(void *arg) 190 { 191 ski_instance_t *instance = (ski_instance_t *) arg; 192 193 while (true) { 194 if (!silent) 195 poll_keyboard(instance); 196 197 thread_usleep(POLL_INTERVAL); 198 } 203 if (!instance) 204 return NULL; 205 206 outdev_t *skidev = malloc(sizeof(outdev_t), FRAME_ATOMIC); 207 if (!skidev) 208 return NULL; 209 210 outdev_initialize("skidev", skidev, &skidev_ops); 211 skidev->data = instance; 212 213 if (!fb_exported) { 214 /* 215 * This is the necessary evil until the userspace driver is entirely 216 * self-sufficient. 217 */ 218 sysinfo_set_item_val("fb", NULL, false); 219 220 fb_exported = true; 221 } 222 223 return skidev; 199 224 } 200 225 … … 202 227 { 203 228 ski_init(); 204 205 ski_instance_t *instance =206 malloc(sizeof(ski_instance_t), FRAME_ATOMIC);207 208 if (instance) {209 instance->thread = thread_create(kskipoll, instance, TASK, 0,210 "kskipoll", true);211 212 if (!instance->thread) {213 free(instance);214 return NULL;215 }216 217 instance->srlnin = NULL;218 }219 220 229 return instance; 221 230 } … … 233 242 } 234 243 235 void ski_kbd_grab(void)236 {237 kbd_disabled = false;238 }239 240 void ski_kbd_release(void)241 {242 kbd_disabled = true;243 }244 245 244 /** @} 246 245 */ -
kernel/arch/ia64/src/ia64.c
r90c8b8d ra71c158 160 160 } 161 161 162 skiout_init(); 162 outdev_t *skidev = skiout_init(); 163 if (skidev) 164 stdout_wire(skidev); 163 165 #endif 164 166 165 167 #ifdef CONFIG_EGA 166 ega_init(EGA_BASE, EGA_VIDEORAM); 168 outdev_t *egadev = ega_init(EGA_BASE, EGA_VIDEORAM); 169 if (egadev) 170 stdout_wire(egadev); 167 171 #endif 168 172 … … 249 253 unative_t sys_tls_set(unative_t addr) 250 254 { 251 return 0; 252 } 253 254 /** Acquire console back for kernel 255 * 256 */ 257 void arch_grab_console(void) 258 { 259 #ifdef MACHINE_ski 260 ski_kbd_grab(); 261 #endif 262 } 263 264 /** Return console to userspace 265 * 266 */ 267 void arch_release_console(void) 268 { 269 #ifdef MACHINE_ski 270 ski_kbd_release(); 271 #endif 255 return 0; 272 256 } 273 257 -
kernel/arch/mips32/src/mips32.c
r90c8b8d ra71c158 144 144 .visual = VISUAL_RGB_8_8_8, 145 145 }; 146 fb_init(&gxemul_prop); 147 #else 146 147 outdev_t *fbdev = fb_init(&gxemul_prop); 148 if (fbdev) 149 stdout_wire(fbdev); 150 #endif 151 148 152 #ifdef CONFIG_MIPS_PRN 149 dsrlnout_init((ioport8_t *) MSIM_KBD_ADDRESS); 150 #endif /* CONFIG_MIPS_PRN */ 151 #endif /* CONFIG_FB */ 153 outdev_t *dsrlndev = dsrlnout_init((ioport8_t *) MSIM_KBD_ADDRESS); 154 if (dsrlndev) 155 stdout_wire(dsrlndev); 156 #endif 152 157 } 153 158 … … 252 257 } 253 258 254 void arch_grab_console(void)255 {256 #ifdef CONFIG_FB257 fb_redraw();258 #endif259 }260 261 /** Return console to userspace262 *263 */264 void arch_release_console(void)265 {266 }267 268 259 /** @} 269 260 */ -
kernel/arch/ppc32/src/ppc32.c
r90c8b8d ra71c158 143 143 .visual = visual, 144 144 }; 145 fb_init(&fb_prop); 146 } 147 148 /* Consider only a single device for now */ 149 return false; 145 146 outdev_t *fbdev = fb_init(&fb_prop); 147 if (fbdev) 148 stdout_wire(fbdev); 149 } 150 151 return true; 150 152 } 151 153 … … 235 237 } 236 238 237 /** Acquire console back for kernel238 *239 */240 void arch_grab_console(void)241 {242 #ifdef CONFIG_FB243 fb_redraw();244 #endif245 }246 247 /** Return console to userspace248 *249 */250 void arch_release_console(void)251 {252 }253 254 239 /** Construct function pointer 255 240 * -
kernel/arch/sparc64/include/drivers/scr.h
r90c8b8d ra71c158 27 27 */ 28 28 29 /** @addtogroup sparc64 29 /** @addtogroup sparc64 30 30 * @{ 31 31 */ … … 50 50 51 51 extern void scr_init(ofw_tree_node_t *node); 52 extern void scr_redraw(void);53 52 54 53 #endif -
kernel/arch/sparc64/include/drivers/sgcn.h
r90c8b8d ra71c158 39 39 #include <console/chardev.h> 40 40 #include <proc/thread.h> 41 #include <synch/spinlock.h> 41 42 42 43 /* number of bytes in the TOC magic, including the NULL-terminator */ 43 #define TOC_MAGIC_BYTES 44 #define TOC_MAGIC_BYTES 8 44 45 45 46 /* number of bytes in the TOC key, including the NULL-terminator */ 46 #define TOC_KEY_SIZE 47 #define TOC_KEY_SIZE 8 47 48 48 49 /* maximum number of entries in the SRAM table of contents */ 49 #define MAX_TOC_ENTRIES 50 #define MAX_TOC_ENTRIES 32 50 51 51 52 /* number of bytes in the SGCN buffer magic, including the NULL-terminator */ 52 #define SGCN_MAGIC_BYTES 53 #define SGCN_MAGIC_BYTES 4 53 54 54 55 /** 55 56 * Entry in the SRAM table of contents. Describes one segment of the SRAM 56 57 * which serves a particular purpose (e.g. OBP serial console, Solaris serial 57 * console, Solaris mailbox,...). 58 * console, Solaris mailbox,...). 58 59 */ 59 60 typedef struct { … … 84 85 /** 85 86 * SGCN buffer header. It is placed at the very beginning of the SGCN 86 * buffer. 87 * buffer. 87 88 */ 88 89 typedef struct { … … 104 105 /** offset within the SGCN buffer of the input buffer write pointer */ 105 106 uint32_t in_wrptr; 106 107 107 108 /** offset within the SGCN buffer of the output buffer start */ 108 109 uint32_t out_begin; … … 119 120 120 121 typedef struct { 122 /** Starting address of SRAM */ 123 uintptr_t sram_begin; 124 125 /** Starting address of the SGCN buffer */ 126 uintptr_t buffer_begin; 127 128 /** 129 * Ensure that writing to the buffer and consequent 130 * update of the write pointer are one atomic operation. 131 */ 132 SPINLOCK_DECLARE(output_lock); 133 134 /** 135 * Prevent the input buffer read/write pointers from 136 * getting to inconsistent state. 137 */ 138 SPINLOCK_DECLARE(input_lock); 139 121 140 thread_t *thread; 122 141 indev_t *srlnin; 123 142 } sgcn_instance_t; 124 143 125 extern void sgcn_grab(void);126 extern void sgcn_release(void);127 144 extern sgcn_instance_t *sgcnin_init(void); 128 145 extern void sgcnin_wire(sgcn_instance_t *, indev_t *); 129 extern voidsgcnout_init(void);146 extern outdev_t *sgcnout_init(void); 130 147 131 148 #endif -
kernel/arch/sparc64/src/console.c
r90c8b8d ra71c158 103 103 } 104 104 #endif 105 105 106 #ifdef CONFIG_SGCN_PRN 106 sgcnout_init(); 107 outdev_t *sgcndev = sgcnout_init(); 108 if (sgcndev) 109 stdout_wire(sgcndev); 107 110 #endif 108 111 } … … 131 134 } 132 135 133 134 /** Acquire console back for kernel135 *136 */137 void arch_grab_console(void)138 {139 #ifdef CONFIG_FB140 scr_redraw();141 #endif142 143 #ifdef CONFIG_SGCN_KBD144 sgcn_grab();145 #endif146 }147 148 /** Return console to userspace149 *150 */151 void arch_release_console(void)152 {153 #ifdef CONFIG_SGCN_KBD154 sgcn_release();155 #endif156 }157 158 136 /** @} 159 137 */ -
kernel/arch/sparc64/src/drivers/scr.c
r90c8b8d ra71c158 40 40 #include <genarch/fb/fb.h> 41 41 #include <genarch/fb/visuals.h> 42 #include <console/chardev.h> 43 #include <console/console.h> 42 44 #include <arch/types.h> 43 45 #include <string.h> … … 238 240 .visual = visual, 239 241 }; 240 fb_init(&props); 242 243 outdev_t *fbdev = fb_init(&props); 244 if (fbdev) 245 stdout_wire(fbdev); 241 246 } 242 247 243 void scr_redraw(void)244 {245 fb_redraw();246 }247 248 248 /** @} 249 249 */ -
kernel/arch/sparc64/src/drivers/sgcn.c
r90c8b8d ra71c158 49 49 #include <synch/spinlock.h> 50 50 51 #define POLL_INTERVAL 51 #define POLL_INTERVAL 10000 52 52 53 53 /* … … 57 57 * not sure whether this value is valid generally. 58 58 */ 59 #define SBBC_START 59 #define SBBC_START 0x63000000000 60 60 61 61 /* offset of SRAM within the SBBC memory */ 62 #define SBBC_SRAM_OFFSET 62 #define SBBC_SRAM_OFFSET 0x900000 63 63 64 64 /* size (in bytes) of the physical memory area which will be mapped */ 65 #define MAPPED_AREA_SIZE 65 #define MAPPED_AREA_SIZE (128 * 1024) 66 66 67 67 /* magic string contained at the beginning of SRAM */ 68 #define SRAM_TOC_MAGIC 68 #define SRAM_TOC_MAGIC "TOCSRAM" 69 69 70 70 /* … … 78 78 * Therefore HelenOS needs to make no such arrangements any more. 79 79 */ 80 #define CONSOLE_KEY 80 #define CONSOLE_KEY "OBPCONS" 81 81 82 82 /* magic string contained at the beginning of the console buffer */ 83 #define SGCN_BUFFER_MAGIC 83 #define SGCN_BUFFER_MAGIC "CON" 84 84 85 85 /* … … 87 87 * offset from the SRAM beginning. 88 88 */ 89 #define SRAM(type, offset) ((type *) (sram_begin + (offset)))89 #define SRAM(type, offset) ((type *) (instance->sram_begin + (offset))) 90 90 91 91 /* Returns a pointer to the SRAM table of contents. */ 92 #define SRAM_TOC 92 #define SRAM_TOC (SRAM(iosram_toc_t, 0)) 93 93 94 94 /* … … 97 97 */ 98 98 #define SGCN_BUFFER(type, offset) \ 99 ((type *) ( sgcn_buffer_begin + (offset)))99 ((type *) (instance->buffer_begin + (offset))) 100 100 101 101 /** Returns a pointer to the console buffer header. */ 102 #define SGCN_BUFFER_HEADER (SGCN_BUFFER(sgcn_buffer_header_t, 0)) 103 104 /** starting address of SRAM, will be set by the init_sram_begin function */ 105 static uintptr_t sram_begin; 106 107 /** 108 * starting address of the SGCN buffer, will be set by the 109 * init_sgcn_buffer_begin function 110 */ 111 static uintptr_t sgcn_buffer_begin; 112 113 /* true iff the kernel driver should ignore pressed keys */ 114 static bool kbd_disabled; 115 116 /* 117 * Ensures that writing to the buffer and consequent update of the write pointer 118 * are together one atomic operation. 119 */ 120 SPINLOCK_INITIALIZE(sgcn_output_lock); 121 122 /* 123 * Prevents the input buffer read/write pointers from getting to inconsistent 124 * state. 125 */ 126 SPINLOCK_INITIALIZE(sgcn_input_lock); 127 128 129 /* functions referenced from definitions of I/O operations structures */ 102 #define SGCN_BUFFER_HEADER (SGCN_BUFFER(sgcn_buffer_header_t, 0)) 103 130 104 static void sgcn_putchar(outdev_t *, const wchar_t, bool); 131 105 132 /** SGCN output device operations */ 133 static outdev_operations_t sgcnout_ops = { 134 . write = sgcn_putchar106 static outdev_operations_t sgcndev_ops = { 107 .write = sgcn_putchar, 108 .redraw = NULL 135 109 }; 136 110 137 static outdev_t sgcnout; /**< SGCN output device. */111 static sgcn_instance_t *instance = NULL; 138 112 139 113 /** … … 158 132 static void init_sram_begin(void) 159 133 { 160 ofw_tree_node_t *chosen; 161 ofw_tree_property_t *iosram_toc; 162 uintptr_t sram_begin_physical; 163 164 chosen = ofw_tree_lookup("/chosen"); 134 ASSERT(instance) 135 136 ofw_tree_node_t *chosen = ofw_tree_lookup("/chosen"); 165 137 if (!chosen) 166 138 panic("Cannot find '/chosen'."); 167 168 iosram_toc = ofw_tree_getprop(chosen, "iosram-toc"); 139 140 ofw_tree_property_t *iosram_toc = 141 ofw_tree_getprop(chosen, "iosram-toc"); 169 142 if (!iosram_toc) 170 143 panic("Cannot find property 'iosram-toc'."); 171 144 if (!iosram_toc->value) 172 145 panic("Cannot find SRAM TOC."); 173 174 sram_begin_physical = SBBC_START + SBBC_SRAM_OFFSET146 147 uintptr_t sram_begin_physical = SBBC_START + SBBC_SRAM_OFFSET 175 148 + *((uint32_t *) iosram_toc->value); 176 sram_begin = hw_map(sram_begin_physical, MAPPED_AREA_SIZE);149 instance->sram_begin = hw_map(sram_begin_physical, MAPPED_AREA_SIZE); 177 150 178 151 register_sram(sram_begin_physical); 152 } 153 154 /** 155 * Function regularly called by the keyboard polling thread. Finds out whether 156 * there are some unread characters in the input queue. If so, it picks them up 157 * and sends them to the upper layers of HelenOS. 158 */ 159 static void sgcn_poll(sgcn_instance_t *instance) 160 { 161 uint32_t begin = SGCN_BUFFER_HEADER->in_begin; 162 uint32_t end = SGCN_BUFFER_HEADER->in_end; 163 uint32_t size = end - begin; 164 165 if (silent) 166 return; 167 168 spinlock_lock(&instance->input_lock); 169 170 /* we need pointers to volatile variables */ 171 volatile char *buf_ptr = (volatile char *) 172 SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr); 173 volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr); 174 volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr); 175 176 while (*in_rdptr_ptr != *in_wrptr_ptr) { 177 buf_ptr = (volatile char *) 178 SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr); 179 char c = *buf_ptr; 180 *in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin; 181 182 indev_push_character(instance->srlnin, c); 183 } 184 185 spinlock_unlock(&instance->input_lock); 186 } 187 188 /** 189 * Polling thread function. 190 */ 191 static void ksgcnpoll(void *instance) { 192 while (true) { 193 if (!silent) 194 sgcn_poll(instance); 195 196 thread_usleep(POLL_INTERVAL); 197 } 179 198 } 180 199 … … 190 209 * under the sram.buffer.offset sysinfo key. 191 210 */ 192 static void sgcn_buffer_begin_init(void) 193 { 194 static bool initialized; 195 196 if (initialized) 211 static void sgcn_init(void) 212 { 213 if (instance) 197 214 return; 198 199 init_sram_begin(); 200 201 ASSERT(str_cmp(SRAM_TOC->magic, SRAM_TOC_MAGIC) == 0); 202 203 /* lookup TOC entry with the correct key */ 204 uint32_t i; 205 for (i = 0; i < MAX_TOC_ENTRIES; i++) { 206 if (str_cmp(SRAM_TOC->keys[i].key, CONSOLE_KEY) == 0) 207 break; 208 } 209 ASSERT(i < MAX_TOC_ENTRIES); 210 211 sgcn_buffer_begin = sram_begin + SRAM_TOC->keys[i].offset; 212 213 sysinfo_set_item_val("sram.buffer.offset", NULL, 214 SRAM_TOC->keys[i].offset); 215 216 initialized = true; 215 216 instance = malloc(sizeof(sgcn_instance_t), FRAME_ATOMIC); 217 218 if (instance) { 219 instance->thread = thread_create(ksgcnpoll, instance, TASK, 0, 220 "ksgcnpoll", true); 221 222 if (!instance->thread) { 223 free(instance); 224 instance = NULL; 225 return; 226 } 227 228 init_sram_begin(); 229 230 ASSERT(str_cmp(SRAM_TOC->magic, SRAM_TOC_MAGIC) == 0); 231 232 /* Lookup TOC entry with the correct key */ 233 uint32_t i; 234 for (i = 0; i < MAX_TOC_ENTRIES; i++) { 235 if (str_cmp(SRAM_TOC->keys[i].key, CONSOLE_KEY) == 0) 236 break; 237 } 238 ASSERT(i < MAX_TOC_ENTRIES); 239 240 instance->buffer_begin = 241 instance->sram_begin + SRAM_TOC->keys[i].offset; 242 243 sysinfo_set_item_val("sram.buffer.offset", NULL, 244 SRAM_TOC->keys[i].offset); 245 246 instance->srlnin = NULL; 247 } 217 248 } 218 249 … … 228 259 uint32_t size = end - begin; 229 260 230 /* we need pointers to volatile variables */261 /* We need pointers to volatile variables */ 231 262 volatile char *buf_ptr = (volatile char *) 232 263 SGCN_BUFFER(char, SGCN_BUFFER_HEADER->out_wrptr); 233 264 volatile uint32_t *out_wrptr_ptr = &(SGCN_BUFFER_HEADER->out_wrptr); 234 265 volatile uint32_t *out_rdptr_ptr = &(SGCN_BUFFER_HEADER->out_rdptr); 235 266 236 267 /* 237 268 * Write the character and increment the write pointer modulo the … … 249 280 */ 250 281 uint32_t new_wrptr = (((*out_wrptr_ptr) - begin + 1) % size) + begin; 251 while (*out_rdptr_ptr == new_wrptr) 252 ;282 while (*out_rdptr_ptr == new_wrptr); 283 253 284 *buf_ptr = c; 254 285 *out_wrptr_ptr = new_wrptr; … … 259 290 * character is converted to CRLF. 260 291 */ 261 static void sgcn_putchar(outdev_t * od, const wchar_t ch, bool silent)292 static void sgcn_putchar(outdev_t *dev, const wchar_t ch, bool silent) 262 293 { 263 294 if (!silent) { 264 spinlock_lock(& sgcn_output_lock);295 spinlock_lock(&instance->output_lock); 265 296 266 297 if (ascii_check(ch)) { … … 271 302 sgcn_do_putchar(U_SPECIAL); 272 303 273 spinlock_unlock(&sgcn_output_lock); 274 } 275 } 276 277 /** 278 * Grabs the input for kernel. 279 */ 280 void sgcn_grab(void) 281 { 282 kbd_disabled = false; 283 } 284 285 /** 286 * Releases the input so that userspace can use it. 287 */ 288 void sgcn_release(void) 289 { 290 kbd_disabled = true; 291 } 292 293 /** 294 * Function regularly called by the keyboard polling thread. Finds out whether 295 * there are some unread characters in the input queue. If so, it picks them up 296 * and sends them to the upper layers of HelenOS. 297 */ 298 static void sgcn_poll(sgcn_instance_t *instance) 299 { 300 uint32_t begin = SGCN_BUFFER_HEADER->in_begin; 301 uint32_t end = SGCN_BUFFER_HEADER->in_end; 302 uint32_t size = end - begin; 303 304 if (kbd_disabled) 305 return; 306 307 spinlock_lock(&sgcn_input_lock); 308 309 /* we need pointers to volatile variables */ 310 volatile char *buf_ptr = (volatile char *) 311 SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr); 312 volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr); 313 volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr); 314 315 while (*in_rdptr_ptr != *in_wrptr_ptr) { 316 buf_ptr = (volatile char *) 317 SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr); 318 char c = *buf_ptr; 319 *in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin; 320 321 indev_push_character(instance->srlnin, c); 322 } 323 324 spinlock_unlock(&sgcn_input_lock); 325 } 326 327 /** 328 * Polling thread function. 329 */ 330 static void ksgcnpoll(void *instance) { 331 while (1) { 332 if (!silent) 333 sgcn_poll(instance); 334 thread_usleep(POLL_INTERVAL); 304 spinlock_unlock(&instance->output_lock); 335 305 } 336 306 } … … 341 311 sgcn_instance_t *sgcnin_init(void) 342 312 { 343 sgcn_buffer_begin_init(); 344 345 sgcn_instance_t *instance = 346 malloc(sizeof(sgcn_instance_t), FRAME_ATOMIC); 347 348 if (instance) { 349 instance->srlnin = NULL; 350 instance->thread = thread_create(ksgcnpoll, instance, TASK, 0, 351 "ksgcnpoll", true); 352 353 if (!instance->thread) { 354 free(instance); 355 return NULL; 356 } 357 } 358 313 sgcn_init(); 359 314 return instance; 360 315 } … … 364 319 ASSERT(instance); 365 320 ASSERT(srlnin); 366 321 367 322 instance->srlnin = srlnin; 368 323 thread_ready(instance->thread); 369 324 370 325 sysinfo_set_item_val("kbd", NULL, true); 371 326 } … … 374 329 * A public function which initializes output to the Serengeti console. 375 330 */ 376 void sgcnout_init(void) 377 { 378 sgcn_buffer_begin_init(); 379 380 sysinfo_set_item_val("fb.kind", NULL, 4); 381 382 outdev_initialize("sgcnout", &sgcnout, &sgcnout_ops); 383 stdout_wire(&sgcnout); 331 outdev_t *sgcnout_init(void) 332 { 333 sgcn_init(); 334 if (!instance) 335 return NULL; 336 337 outdev_t *sgcndev = malloc(sizeof(outdev_t), FRAME_ATOMIC); 338 if (!sgcndev) 339 return NULL; 340 341 outdev_initialize("sgcndev", sgcndev, &sgcndev_ops); 342 sgcndev->data = instance; 343 344 if (!fb_exported) { 345 /* 346 * This is the necessary evil until the userspace driver is entirely 347 * self-sufficient. 348 */ 349 sysinfo_set_item_val("fb.kind", NULL, 4); 350 351 fb_exported = true; 352 } 353 354 return sgcndev; 384 355 } 385 356 -
kernel/genarch/include/drivers/dsrln/dsrlnout.h
r90c8b8d ra71c158 40 40 #include <arch/types.h> 41 41 #include <typedefs.h> 42 #include <console/chardev.h> 42 43 43 extern voiddsrlnout_init(ioport8_t *);44 extern outdev_t *dsrlnout_init(ioport8_t *); 44 45 45 46 #endif -
kernel/genarch/include/drivers/ega/ega.h
r90c8b8d ra71c158 38 38 #include <arch/types.h> 39 39 #include <typedefs.h> 40 #include <console/chardev.h> 40 41 41 42 #define EGA_COLS 80 … … 48 49 #define EGA_DATA_REG 1 49 50 50 extern void ega_redraw(void); 51 extern void ega_init(ioport8_t *, uintptr_t); 51 extern outdev_t *ega_init(ioport8_t *, uintptr_t); 52 52 53 53 #endif -
kernel/genarch/include/fb/fb.h
r90c8b8d ra71c158 37 37 38 38 #include <arch/types.h> 39 #include <synch/spinlock.h> 39 #include <console/chardev.h> 40 #include <genarch/fb/visuals.h> 40 41 41 42 /** … … 45 46 /** Physical address of the framebuffer device. */ 46 47 uintptr_t addr; 47 48 48 49 /** 49 50 * Address where the first (top left) pixel is mapped, … … 51 52 */ 52 53 unsigned int offset; 53 54 54 55 /** Screen width in pixels. */ 55 56 unsigned int x; 56 57 57 58 /** Screen height in pixels. */ 58 59 unsigned int y; 59 60 60 61 /** Bytes per one scanline. */ 61 62 unsigned int scan; 62 63 63 64 /** Color model. */ 64 unsigned int visual;65 visual_t visual; 65 66 } fb_properties_t; 66 67 67 SPINLOCK_EXTERN(fb_lock); 68 69 void fb_redraw(void); 70 bool fb_init(fb_properties_t *props); 68 outdev_t *fb_init(fb_properties_t *props); 71 69 72 70 #endif -
kernel/genarch/src/drivers/dsrln/dsrlnout.c
r90c8b8d ra71c158 35 35 */ 36 36 37 38 37 #include <genarch/drivers/dsrln/dsrlnout.h> 39 38 #include <console/chardev.h> 40 39 #include <arch/asm.h> 40 #include <mm/slab.h> 41 41 #include <console/console.h> 42 42 #include <sysinfo/sysinfo.h> 43 43 #include <string.h> 44 44 45 static ioport8_t *dsrlnout_base; 45 typedef struct { 46 ioport8_t *base; 47 } dsrlnout_instance_t; 46 48 47 static void dsrlnout_putchar(outdev_t *dev __attribute__((unused)), const wchar_t ch, bool silent)49 static void dsrlnout_putchar(outdev_t *dev, const wchar_t ch, bool silent) 48 50 { 51 dsrlnout_instance_t *instance = (dsrlnout_instance_t *) dev->data; 52 49 53 if (!silent) { 50 54 if (ascii_check(ch)) 51 pio_write_8( dsrlnout_base, ch);55 pio_write_8(instance->base, ch); 52 56 else 53 pio_write_8( dsrlnout_base, U_SPECIAL);57 pio_write_8(instance->base, U_SPECIAL); 54 58 } 55 59 } 56 60 57 static outdev_ t dsrlnout_console;58 static outdev_operations_t dsrlnout_ops = { 59 . write = dsrlnout_putchar61 static outdev_operations_t dsrlndev_ops = { 62 .write = dsrlnout_putchar, 63 .redraw = NULL 60 64 }; 61 65 62 voiddsrlnout_init(ioport8_t *base)66 outdev_t *dsrlnout_init(ioport8_t *base) 63 67 { 64 /* Initialize the software structure. */ 65 dsrlnout_base = base; 68 outdev_t *dsrlndev = malloc(sizeof(outdev_t), FRAME_ATOMIC); 69 if (!dsrlndev) 70 return NULL; 66 71 67 outdev_initialize("dsrlnout", &dsrlnout_console, &dsrlnout_ops); 68 stdout_wire(&dsrlnout_console); 72 dsrlnout_instance_t *instance = malloc(sizeof(dsrlnout_instance_t), FRAME_ATOMIC); 73 if (!instance) { 74 free(dsrlndev); 75 return NULL; 76 } 69 77 70 sysinfo_set_item_val("fb", NULL, true); 71 sysinfo_set_item_val("fb.kind", NULL, 3); 72 sysinfo_set_item_val("fb.address.physical", NULL, KA2PA(base)); 78 outdev_initialize("dsrlndev", dsrlndev, &dsrlndev_ops); 79 dsrlndev->data = instance; 80 81 instance->base = base; 82 83 if (!fb_exported) { 84 /* 85 * This is the necessary evil until the userspace driver is entirely 86 * self-sufficient. 87 */ 88 sysinfo_set_item_val("fb", NULL, true); 89 sysinfo_set_item_val("fb.kind", NULL, 3); 90 sysinfo_set_item_val("fb.address.physical", NULL, KA2PA(base)); 91 92 fb_exported = true; 93 } 94 95 return dsrlndev; 73 96 } 74 97 -
kernel/genarch/src/drivers/ega/ega.c
r90c8b8d ra71c158 56 56 */ 57 57 58 SPINLOCK_INITIALIZE(egalock);59 static uint32_t ega_cursor;60 static uint8_t *videoram;61 static uint8_t *backbuf;62 static ioport8_t *ega_base;63 64 58 #define SPACE 0x20 65 59 #define STYLE 0x1e … … 68 62 #define EMPTY_CHAR ((STYLE << 8) | SPACE) 69 63 64 typedef struct { 65 SPINLOCK_DECLARE(lock); 66 67 uint32_t cursor; 68 uint8_t *addr; 69 uint8_t *backbuf; 70 ioport8_t *base; 71 } ega_instance_t; 72 73 static void ega_putchar(outdev_t *dev, wchar_t ch, bool silent); 74 static void ega_redraw(outdev_t *dev); 75 76 static outdev_operations_t egadev_ops = { 77 .write = ega_putchar, 78 .redraw = ega_redraw 79 }; 80 70 81 static uint16_t ega_oem_glyph(const wchar_t ch) 71 82 { … … 427 438 * This function takes care of scrolling. 428 439 */ 429 static void ega_check_cursor( bool silent)430 { 431 if ( ega_cursor < EGA_SCREEN)440 static void ega_check_cursor(ega_instance_t *instance, bool silent) 441 { 442 if (instance->cursor < EGA_SCREEN) 432 443 return; 433 444 434 memmove((void *) backbuf, (void *) (backbuf + EGA_COLS * 2), 445 memmove((void *) instance->backbuf, 446 (void *) (instance->backbuf + EGA_COLS * 2), 435 447 (EGA_SCREEN - EGA_COLS) * 2); 436 memsetw(backbuf + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR); 448 memsetw(instance->backbuf + (EGA_SCREEN - EGA_COLS) * 2, 449 EGA_COLS, EMPTY_CHAR); 437 450 438 451 if (!silent) { 439 memmove((void *) videoram, (void *) (videoram + EGA_COLS * 2), 452 memmove((void *) instance->addr, 453 (void *) (instance->addr + EGA_COLS * 2), 440 454 (EGA_SCREEN - EGA_COLS) * 2); 441 memsetw(videoram + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR); 442 } 443 444 ega_cursor = ega_cursor - EGA_COLS; 445 } 446 447 static void ega_show_cursor(bool silent) 455 memsetw(instance->addr + (EGA_SCREEN - EGA_COLS) * 2, 456 EGA_COLS, EMPTY_CHAR); 457 } 458 459 instance->cursor = instance->cursor - EGA_COLS; 460 } 461 462 static void ega_show_cursor(ega_instance_t *instance, bool silent) 448 463 { 449 464 if (!silent) { 450 pio_write_8( ega_base + EGA_INDEX_REG, 0x0a);451 uint8_t stat = pio_read_8( ega_base + EGA_DATA_REG);452 pio_write_8( ega_base + EGA_INDEX_REG, 0x0a);453 pio_write_8( ega_base + EGA_DATA_REG, stat & (~(1 << 5)));454 } 455 } 456 457 static void ega_move_cursor( bool silent)465 pio_write_8(instance->base + EGA_INDEX_REG, 0x0a); 466 uint8_t stat = pio_read_8(instance->base + EGA_DATA_REG); 467 pio_write_8(instance->base + EGA_INDEX_REG, 0x0a); 468 pio_write_8(instance->base + EGA_DATA_REG, stat & (~(1 << 5))); 469 } 470 } 471 472 static void ega_move_cursor(ega_instance_t *instance, bool silent) 458 473 { 459 474 if (!silent) { 460 pio_write_8(ega_base + EGA_INDEX_REG, 0x0e); 461 pio_write_8(ega_base + EGA_DATA_REG, (uint8_t) ((ega_cursor >> 8) & 0xff)); 462 pio_write_8(ega_base + EGA_INDEX_REG, 0x0f); 463 pio_write_8(ega_base + EGA_DATA_REG, (uint8_t) (ega_cursor & 0xff)); 464 } 465 } 466 467 static void ega_sync_cursor(bool silent) 475 pio_write_8(instance->base + EGA_INDEX_REG, 0x0e); 476 pio_write_8(instance->base + EGA_DATA_REG, 477 (uint8_t) ((instance->cursor >> 8) & 0xff)); 478 pio_write_8(instance->base + EGA_INDEX_REG, 0x0f); 479 pio_write_8(instance->base + EGA_DATA_REG, 480 (uint8_t) (instance->cursor & 0xff)); 481 } 482 } 483 484 static void ega_sync_cursor(ega_instance_t *instance, bool silent) 468 485 { 469 486 if (!silent) { 470 pio_write_8( ega_base + EGA_INDEX_REG, 0x0e);471 uint8_t hi = pio_read_8( ega_base + EGA_DATA_REG);472 pio_write_8( ega_base + EGA_INDEX_REG, 0x0f);473 uint8_t lo = pio_read_8( ega_base + EGA_DATA_REG);487 pio_write_8(instance->base + EGA_INDEX_REG, 0x0e); 488 uint8_t hi = pio_read_8(instance->base + EGA_DATA_REG); 489 pio_write_8(instance->base + EGA_INDEX_REG, 0x0f); 490 uint8_t lo = pio_read_8(instance->base + EGA_DATA_REG); 474 491 475 ega_cursor = (hi << 8) | lo;492 instance->cursor = (hi << 8) | lo; 476 493 } else 477 ega_cursor = 0; 478 479 if (ega_cursor >= EGA_SCREEN) 480 ega_cursor = 0; 481 482 if ((ega_cursor % EGA_COLS) != 0) 483 ega_cursor = (ega_cursor + EGA_COLS) - ega_cursor % EGA_COLS; 484 485 memsetw(backbuf + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR); 494 instance->cursor = 0; 495 496 if (instance->cursor >= EGA_SCREEN) 497 instance->cursor = 0; 498 499 if ((instance->cursor % EGA_COLS) != 0) 500 instance->cursor = 501 (instance->cursor + EGA_COLS) - instance->cursor % EGA_COLS; 502 503 memsetw(instance->backbuf + instance->cursor * 2, 504 EGA_SCREEN - instance->cursor, EMPTY_CHAR); 486 505 487 506 if (!silent) 488 memsetw(videoram + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR); 489 490 ega_check_cursor(silent); 491 ega_move_cursor(silent); 492 ega_show_cursor(silent); 493 } 494 495 static void ega_display_char(wchar_t ch, bool silent) 507 memsetw(instance->addr + instance->cursor * 2, 508 EGA_SCREEN - instance->cursor, EMPTY_CHAR); 509 510 ega_check_cursor(instance, silent); 511 ega_move_cursor(instance, silent); 512 ega_show_cursor(instance, silent); 513 } 514 515 static void ega_display_char(ega_instance_t *instance, wchar_t ch, bool silent) 496 516 { 497 517 uint16_t index = ega_oem_glyph(ch); … … 507 527 } 508 528 509 backbuf[ega_cursor * 2] = glyph;510 backbuf[ega_cursor * 2 + 1] = style;529 instance->backbuf[instance->cursor * 2] = glyph; 530 instance->backbuf[instance->cursor * 2 + 1] = style; 511 531 512 532 if (!silent) { 513 videoram[ega_cursor * 2] = glyph;514 videoram[ega_cursor * 2 + 1] = style;515 } 516 } 517 518 static void ega_putchar(outdev_t *dev __attribute__((unused)), wchar_t ch, bool silent)519 { 520 ipl_t ipl;521 522 ipl = interrupts_disable();523 spinlock_lock(& egalock);533 instance->addr[instance->cursor * 2] = glyph; 534 instance->addr[instance->cursor * 2 + 1] = style; 535 } 536 } 537 538 static void ega_putchar(outdev_t *dev, wchar_t ch, bool silent) 539 { 540 ega_instance_t *instance = (ega_instance_t *) dev->data; 541 542 ipl_t ipl = interrupts_disable(); 543 spinlock_lock(&instance->lock); 524 544 525 545 switch (ch) { 526 546 case '\n': 527 ega_cursor = (ega_cursor + EGA_COLS) - ega_cursor % EGA_COLS; 547 instance->cursor = (instance->cursor + EGA_COLS) 548 - instance->cursor % EGA_COLS; 528 549 break; 529 550 case '\t': 530 ega_cursor = (ega_cursor + 8) - ega_cursor % 8; 551 instance->cursor = (instance->cursor + 8) 552 - instance->cursor % 8; 531 553 break; 532 554 case '\b': 533 if ( ega_cursor % EGA_COLS)534 ega_cursor--;555 if (instance->cursor % EGA_COLS) 556 instance->cursor--; 535 557 break; 536 558 default: 537 ega_display_char( ch, silent);538 ega_cursor++;559 ega_display_char(instance, ch, silent); 560 instance->cursor++; 539 561 break; 540 562 } 541 ega_check_cursor( silent);542 ega_move_cursor( silent);543 544 spinlock_unlock(& egalock);563 ega_check_cursor(instance, silent); 564 ega_move_cursor(instance, silent); 565 566 spinlock_unlock(&instance->lock); 545 567 interrupts_restore(ipl); 546 568 } 547 569 548 static outdev_t ega_console; 549 static outdev_operations_t ega_ops = { 550 .write = ega_putchar 551 }; 552 553 void ega_init(ioport8_t *base, uintptr_t videoram_phys) 554 { 555 /* Initialize the software structure. */ 556 ega_base = base; 557 558 backbuf = (uint8_t *) malloc(EGA_VRAM_SIZE, 0); 559 if (!backbuf) 560 panic("Unable to allocate backbuffer."); 561 562 videoram = (uint8_t *) hw_map(videoram_phys, EGA_VRAM_SIZE); 570 static void ega_redraw(outdev_t *dev) 571 { 572 ega_instance_t *instance = (ega_instance_t *) dev->data; 573 574 ipl_t ipl = interrupts_disable(); 575 spinlock_lock(&instance->lock); 576 577 memcpy(instance->addr, instance->backbuf, EGA_VRAM_SIZE); 578 ega_move_cursor(instance, silent); 579 ega_show_cursor(instance, silent); 580 581 spinlock_unlock(&instance->lock); 582 interrupts_restore(ipl); 583 } 584 585 outdev_t *ega_init(ioport8_t *base, uintptr_t addr) 586 { 587 outdev_t *egadev = malloc(sizeof(outdev_t), FRAME_ATOMIC); 588 if (!egadev) 589 return NULL; 590 591 ega_instance_t *instance = malloc(sizeof(ega_instance_t), FRAME_ATOMIC); 592 if (!instance) { 593 free(egadev); 594 return NULL; 595 } 596 597 outdev_initialize("egadev", egadev, &egadev_ops); 598 egadev->data = instance; 599 600 spinlock_initialize(&instance->lock, "*ega_lock"); 601 602 instance->base = base; 603 instance->addr = (uint8_t *) hw_map(addr, EGA_VRAM_SIZE); 604 if (!instance->addr) { 605 LOG("Unable to EGA video memory."); 606 free(instance); 607 free(egadev); 608 return NULL; 609 } 610 611 instance->backbuf = (uint8_t *) malloc(EGA_VRAM_SIZE, 0); 612 if (!instance->backbuf) { 613 LOG("Unable to allocate backbuffer."); 614 free(instance); 615 free(egadev); 616 return NULL; 617 } 563 618 564 619 /* Synchronize the back buffer and cursor position. */ 565 memcpy( backbuf, videoram, EGA_VRAM_SIZE);566 ega_sync_cursor( silent);567 568 outdev_initialize("ega", &ega_console, &ega_ops);569 stdout_wire(&ega_console);570 571 sysinfo_set_item_val("fb", NULL, true);572 sysinfo_set_item_val("fb.kind", NULL, 2);573 sysinfo_set_item_val("fb.width", NULL, EGA_COLS);574 sysinfo_set_item_val("fb.height", NULL, EGA_ROWS);575 sysinfo_set_item_val("fb.blinking", NULL, true);576 sysinfo_set_item_val("fb.address.physical", NULL, videoram_phys);577 } 578 579 void ega_redraw(void) 580 { 581 memcpy(videoram, backbuf, EGA_VRAM_SIZE);582 ega_move_cursor(silent);583 ega_show_cursor(silent);620 memcpy(instance->backbuf, instance->addr, EGA_VRAM_SIZE); 621 ega_sync_cursor(instance, silent); 622 623 if (!fb_exported) { 624 /* 625 * This is the necessary evil until the userspace driver is entirely 626 * self-sufficient. 627 */ 628 sysinfo_set_item_val("fb", NULL, true); 629 sysinfo_set_item_val("fb.kind", NULL, 2); 630 sysinfo_set_item_val("fb.width", NULL, EGA_COLS); 631 sysinfo_set_item_val("fb.height", NULL, EGA_ROWS); 632 sysinfo_set_item_val("fb.blinking", NULL, true); 633 sysinfo_set_item_val("fb.address.physical", NULL, addr); 634 635 fb_exported = true; 636 } 637 638 return egadev; 584 639 } 585 640 -
kernel/genarch/src/fb/fb.c
r90c8b8d ra71c158 53 53 #include <byteorder.h> 54 54 55 SPINLOCK_INITIALIZE(fb_lock);56 57 static uint8_t *fb_addr;58 static uint16_t *backbuf;59 static uint8_t *glyphs;60 static uint8_t *bgscan;61 62 static unsigned int xres;63 static unsigned int yres;64 65 static unsigned int ylogo;66 static unsigned int ytrim;67 static unsigned int rowtrim;68 69 static unsigned int scanline;70 static unsigned int glyphscanline;71 72 static unsigned int pixelbytes;73 static unsigned int glyphbytes;74 static unsigned int bgscanbytes;75 76 static unsigned int cols;77 static unsigned int rows;78 static unsigned int position = 0;79 80 55 #define BG_COLOR 0x000080 81 56 #define FG_COLOR 0xffff00 82 57 #define INV_COLOR 0xaaaaaa 83 58 84 #define RED(x, bits) (((x) >> (8 + 8 + 8 - (bits))) & ((1 << (bits)) - 1)) 85 #define GREEN(x, bits) (((x) >> (8 + 8 - (bits))) & ((1 << (bits)) - 1)) 86 #define BLUE(x, bits) (((x) >> (8 - (bits))) & ((1 << (bits)) - 1)) 87 88 #define COL2X(col) ((col) * FONT_WIDTH) 89 #define ROW2Y(row) ((row) * FONT_SCANLINES) 90 91 #define X2COL(x) ((x) / FONT_WIDTH) 92 #define Y2ROW(y) ((y) / FONT_SCANLINES) 93 94 #define FB_POS(x, y) ((y) * scanline + (x) * pixelbytes) 95 #define BB_POS(col, row) ((row) * cols + (col)) 96 #define GLYPH_POS(glyph, y) ((glyph) * glyphbytes + (y) * glyphscanline) 97 98 99 static void (*rgb_conv)(void *, uint32_t); 59 #define RED(x, bits) (((x) >> (8 + 8 + 8 - (bits))) & ((1 << (bits)) - 1)) 60 #define GREEN(x, bits) (((x) >> (8 + 8 - (bits))) & ((1 << (bits)) - 1)) 61 #define BLUE(x, bits) (((x) >> (8 - (bits))) & ((1 << (bits)) - 1)) 62 63 #define COL2X(col) ((col) * FONT_WIDTH) 64 #define ROW2Y(row) ((row) * FONT_SCANLINES) 65 66 #define X2COL(x) ((x) / FONT_WIDTH) 67 #define Y2ROW(y) ((y) / FONT_SCANLINES) 68 69 #define FB_POS(instance, x, y) \ 70 ((y) * (instance)->scanline + (x) * (instance)->pixelbytes) 71 72 #define BB_POS(instance, col, row) \ 73 ((row) * (instance)->cols + (col)) 74 75 #define GLYPH_POS(instance, glyph, y) \ 76 ((glyph) * (instance)->glyphbytes + (y) * (instance)->glyphscanline) 77 78 typedef void (* rgb_conv_t)(void *, uint32_t); 79 80 typedef struct { 81 SPINLOCK_DECLARE(lock); 82 83 uint8_t *addr; 84 uint16_t *backbuf; 85 uint8_t *glyphs; 86 uint8_t *bgscan; 87 88 rgb_conv_t rgb_conv; 89 90 unsigned int xres; 91 unsigned int yres; 92 93 unsigned int ylogo; 94 unsigned int ytrim; 95 unsigned int rowtrim; 96 97 unsigned int scanline; 98 unsigned int glyphscanline; 99 100 unsigned int pixelbytes; 101 unsigned int glyphbytes; 102 unsigned int bgscanbytes; 103 104 unsigned int cols; 105 unsigned int rows; 106 107 unsigned int position; 108 } fb_instance_t; 109 110 static void fb_putchar(outdev_t *dev, wchar_t ch, bool silent); 111 static void fb_redraw_internal(fb_instance_t *instance); 112 static void fb_redraw(outdev_t *dev); 113 114 static outdev_operations_t fbdev_ops = { 115 .write = fb_putchar, 116 .redraw = fb_redraw 117 }; 100 118 101 119 /* … … 169 187 GREEN(rgb, 6) << 5 | BLUE(rgb, 5)); 170 188 } 171 172 189 173 190 /** BGR 3:2:3 … … 179 196 * and setting it to simulate the 8-bit truecolor. 180 197 * 181 * Currently we set the palette on the ia32, amd64 and sparc64 port.198 * Currently we set the palette on the ia32, amd64, ppc32 and sparc64 port. 182 199 * 183 200 * Note that the byte is being inverted by this function. The reason is … … 194 211 } 195 212 196 197 213 /** Hide logo and refresh screen 198 214 * 199 215 */ 200 static void logo_hide(bool silent) 201 { 202 ylogo = 0; 203 ytrim = yres; 204 rowtrim = rows; 216 static void logo_hide(fb_instance_t *instance, bool silent) 217 { 218 instance->ylogo = 0; 219 instance->ytrim = instance->yres; 220 instance->rowtrim = instance->rows; 221 205 222 if (!silent) 206 fb_redraw(); 207 } 208 223 fb_redraw_internal(instance); 224 } 209 225 210 226 /** Draw character at given position 211 227 * 212 228 */ 213 static void glyph_draw(uint16_t glyph, unsigned int col, unsigned int row, bool silent, bool overlay) 229 static void glyph_draw(fb_instance_t *instance, uint16_t glyph, 230 unsigned int col, unsigned int row, bool silent, bool overlay) 214 231 { 215 232 unsigned int x = COL2X(col); … … 217 234 unsigned int yd; 218 235 219 if (y >= ytrim)220 logo_hide( silent);236 if (y >= instance->ytrim) 237 logo_hide(instance, silent); 221 238 222 239 if (!overlay) 223 backbuf[BB_POS(col, row)] = glyph;240 instance->backbuf[BB_POS(instance, col, row)] = glyph; 224 241 225 242 if (!silent) { 226 243 for (yd = 0; yd < FONT_SCANLINES; yd++) 227 memcpy(& fb_addr[FB_POS(x, y + yd +ylogo)],228 & glyphs[GLYPH_POS(glyph, yd)], glyphscanline);229 }230 }231 244 memcpy(&instance->addr[FB_POS(instance, x, y + yd + instance->ylogo)], 245 &instance->glyphs[GLYPH_POS(instance, glyph, yd)], 246 instance->glyphscanline); 247 } 248 } 232 249 233 250 /** Scroll screen down by one row … … 235 252 * 236 253 */ 237 static void screen_scroll( bool silent)238 { 239 if ( ylogo > 0) {240 logo_hide( silent);254 static void screen_scroll(fb_instance_t *instance, bool silent) 255 { 256 if (instance->ylogo > 0) { 257 logo_hide(instance, silent); 241 258 return; 242 259 } … … 245 262 unsigned int row; 246 263 247 for (row = 0; row < rows; row++) {264 for (row = 0; row < instance->rows; row++) { 248 265 unsigned int y = ROW2Y(row); 249 266 unsigned int yd; … … 253 270 unsigned int col; 254 271 255 for (col = 0, x = 0; col < cols; col++,256 x += FONT_WIDTH) {272 for (col = 0, x = 0; col < instance->cols; 273 col++, x += FONT_WIDTH) { 257 274 uint16_t glyph; 258 275 259 if (row < rows - 1) {260 if ( backbuf[BB_POS(col, row)] ==261 backbuf[BB_POS(col, row + 1)])276 if (row < instance->rows - 1) { 277 if (instance->backbuf[BB_POS(instance, col, row)] == 278 instance->backbuf[BB_POS(instance, col, row + 1)]) 262 279 continue; 263 280 264 glyph = backbuf[BB_POS(col, row + 1)];281 glyph = instance->backbuf[BB_POS(instance, col, row + 1)]; 265 282 } else 266 283 glyph = 0; 267 284 268 memcpy(& fb_addr[FB_POS(x, y + yd)],269 & glyphs[GLYPH_POS(glyph, yd)],270 glyphscanline);285 memcpy(&instance->addr[FB_POS(instance, x, y + yd)], 286 &instance->glyphs[GLYPH_POS(instance, glyph, yd)], 287 instance->glyphscanline); 271 288 } 272 289 } … … 274 291 } 275 292 276 memmove(backbuf, &backbuf[BB_POS(0, 1)], cols * (rows - 1) * sizeof(uint16_t)); 277 memsetw(&backbuf[BB_POS(0, rows - 1)], cols, 0); 278 } 279 280 281 static void cursor_put(bool silent) 282 { 283 unsigned int col = position % cols; 284 unsigned int row = position / cols; 285 286 glyph_draw(fb_font_glyph(U_CURSOR), col, row, silent, true); 287 } 288 289 290 static void cursor_remove(bool silent) 291 { 292 unsigned int col = position % cols; 293 unsigned int row = position / cols; 294 295 glyph_draw(backbuf[BB_POS(col, row)], col, row, silent, true); 296 } 297 298 299 /** Print character to screen 300 * 301 * Emulate basic terminal commands. 302 * 303 */ 304 static void fb_putchar(outdev_t *dev, wchar_t ch, bool silent) 305 { 306 spinlock_lock(&fb_lock); 307 308 switch (ch) { 309 case '\n': 310 cursor_remove(silent); 311 position += cols; 312 position -= position % cols; 313 break; 314 case '\r': 315 cursor_remove(silent); 316 position -= position % cols; 317 break; 318 case '\b': 319 cursor_remove(silent); 320 if (position % cols) 321 position--; 322 break; 323 case '\t': 324 cursor_remove(silent); 325 do { 326 glyph_draw(fb_font_glyph(' '), position % cols, 327 position / cols, silent, false); 328 position++; 329 } while ((position % 8) && (position < cols * rows)); 330 break; 331 default: 332 glyph_draw(fb_font_glyph(ch), position % cols, 333 position / cols, silent, false); 334 position++; 335 } 336 337 if (position >= cols * rows) { 338 position -= cols; 339 screen_scroll(silent); 340 } 341 342 cursor_put(silent); 343 344 spinlock_unlock(&fb_lock); 345 } 346 347 static outdev_t fb_console; 348 static outdev_operations_t fb_ops = { 349 .write = fb_putchar 350 }; 351 293 memmove(instance->backbuf, &instance->backbuf[BB_POS(instance, 0, 1)], 294 instance->cols * (instance->rows - 1) * sizeof(uint16_t)); 295 memsetw(&instance->backbuf[BB_POS(instance, 0, instance->rows - 1)], 296 instance->cols, 0); 297 } 298 299 static void cursor_put(fb_instance_t *instance, bool silent) 300 { 301 unsigned int col = instance->position % instance->cols; 302 unsigned int row = instance->position / instance->cols; 303 304 glyph_draw(instance, fb_font_glyph(U_CURSOR), col, row, silent, true); 305 } 306 307 static void cursor_remove(fb_instance_t *instance, bool silent) 308 { 309 unsigned int col = instance->position % instance->cols; 310 unsigned int row = instance->position / instance->cols; 311 312 glyph_draw(instance, instance->backbuf[BB_POS(instance, col, row)], 313 col, row, silent, true); 314 } 352 315 353 316 /** Render glyphs … … 357 320 * 358 321 */ 359 static void glyphs_render( void)322 static void glyphs_render(fb_instance_t *instance) 360 323 { 361 324 /* Prerender glyphs */ … … 376 339 377 340 for (x = 0; x < FONT_WIDTH; x++) { 378 void *dst = &glyphs[GLYPH_POS(glyph, y) + 379 x * pixelbytes]; 341 void *dst = 342 &instance->glyphs[GLYPH_POS(instance, glyph, y) + 343 x * instance->pixelbytes]; 380 344 uint32_t rgb = (fb_font[glyph][y] & 381 345 (1 << (7 - x))) ? fg_color : BG_COLOR; 382 rgb_conv(dst, rgb);346 instance->rgb_conv(dst, rgb); 383 347 } 384 348 } … … 388 352 unsigned int x; 389 353 390 for (x = 0; x < xres; x++) 391 rgb_conv(&bgscan[x * pixelbytes], BG_COLOR); 392 } 393 394 395 /** Refresh the screen 396 * 397 */ 398 void fb_redraw(void) 399 { 400 if (ylogo > 0) { 354 for (x = 0; x < instance->xres; x++) 355 instance->rgb_conv(&instance->bgscan[x * instance->pixelbytes], BG_COLOR); 356 } 357 358 /** Print character to screen 359 * 360 * Emulate basic terminal commands. 361 * 362 */ 363 static void fb_putchar(outdev_t *dev, wchar_t ch, bool silent) 364 { 365 fb_instance_t *instance = (fb_instance_t *) dev->data; 366 spinlock_lock(&instance->lock); 367 368 switch (ch) { 369 case '\n': 370 cursor_remove(instance, silent); 371 instance->position += instance->cols; 372 instance->position -= instance->position % instance->cols; 373 break; 374 case '\r': 375 cursor_remove(instance, silent); 376 instance->position -= instance->position % instance->cols; 377 break; 378 case '\b': 379 cursor_remove(instance, silent); 380 if (instance->position % instance->cols) 381 instance->position--; 382 break; 383 case '\t': 384 cursor_remove(instance, silent); 385 do { 386 glyph_draw(instance, fb_font_glyph(' '), 387 instance->position % instance->cols, 388 instance->position / instance->cols, silent, false); 389 instance->position++; 390 } while ((instance->position % 8) 391 && (instance->position < instance->cols * instance->rows)); 392 break; 393 default: 394 glyph_draw(instance, fb_font_glyph(ch), 395 instance->position % instance->cols, 396 instance->position / instance->cols, silent, false); 397 instance->position++; 398 } 399 400 if (instance->position >= instance->cols * instance->rows) { 401 instance->position -= instance->cols; 402 screen_scroll(instance, silent); 403 } 404 405 cursor_put(instance, silent); 406 407 spinlock_unlock(&instance->lock); 408 } 409 410 static void fb_redraw_internal(fb_instance_t *instance) 411 { 412 if (instance->ylogo > 0) { 401 413 unsigned int y; 402 414 … … 404 416 unsigned int x; 405 417 406 for (x = 0; x < xres; x++)407 rgb_conv(&fb_addr[FB_POS(x, y)],418 for (x = 0; x < instance->xres; x++) 419 instance->rgb_conv(&instance->addr[FB_POS(instance, x, y)], 408 420 (x < LOGO_WIDTH) ? 409 421 fb_logo[y * LOGO_WIDTH + x] : … … 414 426 unsigned int row; 415 427 416 for (row = 0; row < rowtrim; row++) {417 unsigned int y = ylogo + ROW2Y(row);428 for (row = 0; row < instance->rowtrim; row++) { 429 unsigned int y = instance->ylogo + ROW2Y(row); 418 430 unsigned int yd; 419 431 … … 422 434 unsigned int col; 423 435 424 for (col = 0, x = 0; col < cols;436 for (col = 0, x = 0; col < instance->cols; 425 437 col++, x += FONT_WIDTH) { 426 uint16_t glyph = backbuf[BB_POS(col, row)]; 427 void *dst = &fb_addr[FB_POS(x, y + yd)]; 428 void *src = &glyphs[GLYPH_POS(glyph, yd)]; 429 memcpy(dst, src, glyphscanline); 438 uint16_t glyph = 439 instance->backbuf[BB_POS(instance, col, row)]; 440 void *dst = &instance->addr[FB_POS(instance, x, y + yd)]; 441 void *src = &instance->glyphs[GLYPH_POS(instance, glyph, yd)]; 442 memcpy(dst, src, instance->glyphscanline); 430 443 } 431 444 } 432 445 } 433 446 434 if (COL2X( cols) <xres) {447 if (COL2X(instance->cols) < instance->xres) { 435 448 unsigned int y; 436 unsigned int size = (xres - COL2X(cols)) * pixelbytes; 437 438 for (y = ylogo; y < yres; y++) 439 memcpy(&fb_addr[FB_POS(COL2X(cols), y)], bgscan, size); 440 } 441 442 if (ROW2Y(rowtrim) + ylogo < yres) { 449 unsigned int size = 450 (instance->xres - COL2X(instance->cols)) * instance->pixelbytes; 451 452 for (y = instance->ylogo; y < instance->yres; y++) 453 memcpy(&instance->addr[FB_POS(instance, COL2X(instance->cols), y)], 454 instance->bgscan, size); 455 } 456 457 if (ROW2Y(instance->rowtrim) + instance->ylogo < instance->yres) { 443 458 unsigned int y; 444 459 445 for (y = ROW2Y(rowtrim) + ylogo; y < yres; y++) 446 memcpy(&fb_addr[FB_POS(0, y)], bgscan, bgscanbytes); 447 } 448 } 449 460 for (y = ROW2Y(instance->rowtrim) + instance->ylogo; 461 y < instance->yres; y++) 462 memcpy(&instance->addr[FB_POS(instance, 0, y)], 463 instance->bgscan, instance->bgscanbytes); 464 } 465 } 466 467 /** Refresh the screen 468 * 469 */ 470 static void fb_redraw(outdev_t *dev) 471 { 472 fb_instance_t *instance = (fb_instance_t *) dev->data; 473 474 spinlock_lock(&instance->lock); 475 fb_redraw_internal(instance); 476 spinlock_unlock(&instance->lock); 477 } 450 478 451 479 /** Initialize framebuffer as a output character device 452 480 * 453 * @param addr Physical address of the framebuffer 454 * @param x Screen width in pixels 455 * @param y Screen height in pixels 456 * @param scan Bytes per one scanline 457 * @param visual Color model 458 * 459 */ 460 bool fb_init(fb_properties_t *props) 481 */ 482 outdev_t *fb_init(fb_properties_t *props) 461 483 { 462 484 ASSERT(props); … … 465 487 ASSERT(props->scan > 0); 466 488 489 rgb_conv_t rgb_conv; 490 unsigned int pixelbytes; 491 467 492 switch (props->visual) { 468 493 case VISUAL_INDIRECT_8: … … 512 537 default: 513 538 LOG("Unsupported visual."); 514 return false; 515 } 516 517 xres = props->x; 518 yres = props->y; 519 scanline = props->scan; 520 521 cols = X2COL(xres); 522 rows = Y2ROW(yres); 523 524 if (yres > ylogo) { 525 ylogo = LOGO_HEIGHT; 526 rowtrim = rows - Y2ROW(ylogo); 527 if (ylogo % FONT_SCANLINES > 0) 528 rowtrim--; 529 ytrim = ROW2Y(rowtrim); 539 return NULL; 540 } 541 542 outdev_t *fbdev = malloc(sizeof(outdev_t), FRAME_ATOMIC); 543 if (!fbdev) 544 return NULL; 545 546 fb_instance_t *instance = malloc(sizeof(fb_instance_t), FRAME_ATOMIC); 547 if (!instance) { 548 free(fbdev); 549 return NULL; 550 } 551 552 outdev_initialize("fbdev", fbdev, &fbdev_ops); 553 fbdev->data = instance; 554 555 spinlock_initialize(&instance->lock, "*fb_lock"); 556 instance->rgb_conv = rgb_conv; 557 instance->pixelbytes = pixelbytes; 558 instance->xres = props->x; 559 instance->yres = props->y; 560 instance->scanline = props->scan; 561 instance->position = 0; 562 563 instance->cols = X2COL(instance->xres); 564 instance->rows = Y2ROW(instance->yres); 565 566 if (instance->yres > LOGO_HEIGHT) { 567 instance->ylogo = LOGO_HEIGHT; 568 instance->rowtrim = instance->rows - Y2ROW(instance->ylogo); 569 if (instance->ylogo % FONT_SCANLINES > 0) 570 instance->rowtrim--; 571 instance->ytrim = ROW2Y(instance->rowtrim); 530 572 } else { 531 ylogo = 0;532 ytrim =yres;533 rowtrim =rows;534 } 535 536 glyphscanline = FONT_WIDTH *pixelbytes;537 glyphbytes = ROW2Y(glyphscanline);538 bgscanbytes = xres *pixelbytes;539 540 size_t fbsize = scanline *yres;541 size_t bbsize = cols *rows * sizeof(uint16_t);542 size_t glyphsize = FONT_GLYPHS * glyphbytes;543 544 fb_addr = (uint8_t *) hw_map((uintptr_t) props->addr, fbsize);545 if (! fb_addr) {573 instance->ylogo = 0; 574 instance->ytrim = instance->yres; 575 instance->rowtrim = instance->rows; 576 } 577 578 instance->glyphscanline = FONT_WIDTH * instance->pixelbytes; 579 instance->glyphbytes = ROW2Y(instance->glyphscanline); 580 instance->bgscanbytes = instance->xres * instance->pixelbytes; 581 582 size_t fbsize = instance->scanline * instance->yres; 583 size_t bbsize = instance->cols * instance->rows * sizeof(uint16_t); 584 size_t glyphsize = FONT_GLYPHS * instance->glyphbytes; 585 586 instance->addr = (uint8_t *) hw_map((uintptr_t) props->addr, fbsize); 587 if (!instance->addr) { 546 588 LOG("Unable to map framebuffer."); 547 return false; 548 } 549 550 backbuf = (uint16_t *) malloc(bbsize, 0); 551 if (!backbuf) { 589 free(instance); 590 free(fbdev); 591 return NULL; 592 } 593 594 instance->backbuf = (uint16_t *) malloc(bbsize, 0); 595 if (!instance->backbuf) { 552 596 LOG("Unable to allocate backbuffer."); 553 return false; 554 } 555 556 glyphs = (uint8_t *) malloc(glyphsize, 0); 557 if (!glyphs) { 558 free(backbuf); 597 free(instance); 598 free(fbdev); 599 return NULL; 600 } 601 602 instance->glyphs = (uint8_t *) malloc(glyphsize, 0); 603 if (!instance->glyphs) { 559 604 LOG("Unable to allocate glyphs."); 560 return false; 561 } 562 563 bgscan = malloc(bgscanbytes, 0); 564 if (!bgscan) { 565 free(glyphs); 566 free(backbuf); 605 free(instance->backbuf); 606 free(instance); 607 free(fbdev); 608 return NULL; 609 } 610 611 instance->bgscan = malloc(instance->bgscanbytes, 0); 612 if (!instance->bgscan) { 567 613 LOG("Unable to allocate background pixel."); 568 return false; 569 } 570 571 memsetw(backbuf, cols * rows, 0); 572 glyphs_render(); 573 574 sysinfo_set_item_val("fb", NULL, true); 575 sysinfo_set_item_val("fb.kind", NULL, 1); 576 sysinfo_set_item_val("fb.width", NULL, xres); 577 sysinfo_set_item_val("fb.height", NULL, yres); 578 sysinfo_set_item_val("fb.scanline", NULL, scanline); 579 sysinfo_set_item_val("fb.visual", NULL, props->visual); 580 sysinfo_set_item_val("fb.address.physical", NULL, props->addr); 581 582 fb_redraw(); 583 584 outdev_initialize("fb", &fb_console, &fb_ops); 585 stdout_wire(&fb_console); 586 587 return true; 614 free(instance->glyphs); 615 free(instance->backbuf); 616 free(instance); 617 free(fbdev); 618 return NULL; 619 } 620 621 memsetw(instance->backbuf, instance->cols * instance->rows, 0); 622 glyphs_render(instance); 623 624 if (!fb_exported) { 625 /* 626 * This is the necessary evil until the userspace driver is entirely 627 * self-sufficient. 628 */ 629 sysinfo_set_item_val("fb", NULL, true); 630 sysinfo_set_item_val("fb.kind", NULL, 1); 631 sysinfo_set_item_val("fb.width", NULL, instance->xres); 632 sysinfo_set_item_val("fb.height", NULL, instance->yres); 633 sysinfo_set_item_val("fb.scanline", NULL, instance->scanline); 634 sysinfo_set_item_val("fb.visual", NULL, props->visual); 635 sysinfo_set_item_val("fb.address.physical", NULL, props->addr); 636 637 fb_exported = true; 638 } 639 640 fb_redraw(fbdev); 641 return fbdev; 588 642 } 589 643 -
kernel/generic/include/console/chardev.h
r90c8b8d ra71c158 74 74 /** Write character to output. */ 75 75 void (* write)(struct outdev *, wchar_t, bool); 76 77 /** Redraw any previously cached characters. */ 78 void (* redraw)(struct outdev *); 76 79 } outdev_operations_t; 77 80 -
kernel/generic/include/console/console.h
r90c8b8d ra71c158 60 60 extern unative_t sys_debug_disable_console(void); 61 61 62 extern void arch_grab_console(void);63 extern void arch_release_console(void);64 65 62 #endif /* KERN_CONSOLE_H_ */ 66 63 -
kernel/generic/include/sysinfo/sysinfo.h
r90c8b8d ra71c158 38 38 #include <arch/types.h> 39 39 #include <string.h> 40 41 extern bool fb_exported; 40 42 41 43 typedef union sysinfo_item_val { -
kernel/generic/src/console/console.c
r90c8b8d ra71c158 71 71 72 72 /** Kernel log spinlock */ 73 SPINLOCK_ INITIALIZE(klog_lock);73 SPINLOCK_STATIC_INITIALIZE_NAME(klog_lock, "*klog_lock"); 74 74 75 75 /** Physical memory area used for klog buffer */ … … 84 84 85 85 static void stdout_write(outdev_t *dev, wchar_t ch, bool silent); 86 static void stdout_redraw(outdev_t *dev); 86 87 87 88 static outdev_operations_t stdout_ops = { 88 .write = stdout_write 89 .write = stdout_write, 90 .redraw = stdout_redraw 89 91 }; 90 92 … … 122 124 for (cur = dev->list.next; cur != &dev->list; cur = cur->next) { 123 125 outdev_t *sink = list_get_instance(cur, outdev_t, link); 124 sink->op->write(sink, ch, silent); 126 if ((sink) && (sink->op->write)) 127 sink->op->write(sink, ch, silent); 128 } 129 } 130 131 static void stdout_redraw(outdev_t *dev) 132 { 133 link_t *cur; 134 135 for (cur = dev->list.next; cur != &dev->list; cur = cur->next) { 136 outdev_t *sink = list_get_instance(cur, outdev_t, link); 137 if ((sink) && (sink->op->redraw)) 138 sink->op->redraw(sink); 125 139 } 126 140 } … … 156 170 157 171 silent = false; 158 arch_grab_console(); 172 if ((stdout) && (stdout->op->redraw)) 173 stdout->op->redraw(stdout); 159 174 160 175 /* Force the console to print the prompt */ … … 165 180 void release_console(void) 166 181 { 182 // FIXME arch_release_console 167 183 silent = true; 168 arch_release_console();169 184 } 170 185 -
kernel/generic/src/sysinfo/sysinfo.c
r90c8b8d ra71c158 27 27 */ 28 28 29 /** @addtogroup generic 29 /** @addtogroup generic 30 30 * @{ 31 31 */ … … 38 38 #include <syscall/copy.h> 39 39 40 bool fb_exported = false; 40 41 sysinfo_item_t *_root = NULL; 41 42 42 43 43 static sysinfo_item_t *sysinfo_find_item(const char *name, sysinfo_item_t *subtree)
Note:
See TracChangeset
for help on using the changeset viewer.