initcalls: Add initial implementation
Create simple serial subsystem which makes use of initcalls, and convert existing serial drivers to its use.
This commit is contained in:
		| @@ -123,17 +123,17 @@ void console_newline() { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void console_putc(char c) { | ||||
| int console_putc(char c) { | ||||
| 	char *console_buffer_end = console_buffer + chars_per_line * lines; | ||||
| 	char *write_char_at; | ||||
|  | ||||
| 	switch (c) { | ||||
| 		case '\n': | ||||
| 			console_newline(); | ||||
| 			return; | ||||
| 			return 0; | ||||
| 		case '\r': | ||||
| 			curr_char = 0; | ||||
| 			return; | ||||
| 			return 0; | ||||
| 		default: | ||||
| 			break; | ||||
| 	} | ||||
| @@ -148,4 +148,6 @@ void console_putc(char c) { | ||||
| 	*write_char_at = c; | ||||
|  | ||||
| 	console_char_to_fb(c, curr_char++, curr_line); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|   | ||||
							
								
								
									
										37
									
								
								kernel/init.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								kernel/init.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| /* | ||||
|     Copyright (C) 2012, Aaron Lindsay <aaron@aclindsay.com> | ||||
|  | ||||
|     This file is part of Aedrix. | ||||
|  | ||||
|     This program is free software; you can redistribute it and/or modify | ||||
|     it under the terms of the GNU General Public License as published by | ||||
|     the Free Software Foundation; either version 2 of the License, or | ||||
|     (at your option) any later version. | ||||
|  | ||||
|     This program is distributed in the hope that it will be useful, | ||||
|     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|     GNU General Public License for more details. | ||||
|  | ||||
|     You should have received a copy of the GNU General Public License along | ||||
|     with this program; if not, write to the Free Software Foundation, Inc., | ||||
|     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
|  */ | ||||
|  | ||||
| #include <types.h> | ||||
| #include <print.h> | ||||
|  | ||||
| extern uint32 early_initcalls_start, early_initcalls_end; | ||||
| extern uint32 initcalls_start, initcalls_end; | ||||
|  | ||||
| void init_earlyinitcalls() { | ||||
| 	void (**initcall)(); | ||||
| 	for (initcall = (void (**)()) &early_initcalls_start; initcall < (void (**)())&early_initcalls_end; initcall++) | ||||
| 		(*initcall)(); | ||||
| } | ||||
|  | ||||
| void init_initcalls() { | ||||
| 	void (**initcall)(); | ||||
| 	for (initcall = (void (**)()) &initcalls_start; initcall < (void (**)())&initcalls_end; initcall++) | ||||
| 		(*initcall)(); | ||||
| } | ||||
| @@ -7,6 +7,7 @@ OBJS_$(d) := $(d)/atags.o \ | ||||
| 	$(d)/console.o \ | ||||
| 	$(d)/font.o \ | ||||
| 	$(d)/framebuffer.o \ | ||||
| 	$(d)/init.o \ | ||||
| 	$(d)/kmalloc.o \ | ||||
| 	$(d)/list.o \ | ||||
| 	$(d)/math.o \ | ||||
|   | ||||
| @@ -23,22 +23,23 @@ | ||||
|  | ||||
| /* This function exists solely so crashes don't happen if putc() gets | ||||
|  * called before it is initialized. */ | ||||
| void putc_initial(char c) { | ||||
| int putc_initial(char c) { | ||||
| 	(void)c; | ||||
| 	return 0; | ||||
| } | ||||
| void (*print_putc)(char) = &putc_initial; | ||||
| int (*print_putc)(char) = &putc_initial; | ||||
|  | ||||
| void print_init(void (*putcfn)(char)) { | ||||
| void print_init(int (*putcfn)(char)) { | ||||
| 	if (putcfn) | ||||
| 		print_putc = putcfn; | ||||
| } | ||||
|   | ||||
| void puts(void (*putc)(char), const char *s) | ||||
| void puts(int (*putc)(char), const char *s) | ||||
| { | ||||
|     while (*s) putc (*s++); | ||||
| } | ||||
|  | ||||
| void puti(void (*putc)(char), int i) | ||||
| void puti(int (*putc)(char), int i) | ||||
| { | ||||
| 	unsigned int left; | ||||
| 	char buf[1 << (sizeof(int)*8) / 10]; | ||||
| @@ -64,7 +65,7 @@ void puti(void (*putc)(char), int i) | ||||
| 		putc(*p); | ||||
| } | ||||
|  | ||||
| void putx(void (*putc)(char), unsigned int i) { | ||||
| void putx(int (*putc)(char), unsigned int i) { | ||||
| 	int j; | ||||
|  | ||||
| 	puts(putc, "0x"); | ||||
| @@ -78,7 +79,7 @@ void putx(void (*putc)(char), unsigned int i) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void putb(void (*putc)(char), unsigned int i) { | ||||
| void putb(int (*putc)(char), unsigned int i) { | ||||
| 	int j; | ||||
|  | ||||
| 	puts(putc, "0b"); | ||||
| @@ -88,7 +89,7 @@ void putb(void (*putc)(char), unsigned int i) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int _print(void (*putc)(char), char *fmt, va_list arg) { | ||||
| int _print(int (*putc)(char), char *fmt, va_list arg) { | ||||
| 	char *c; | ||||
| 	for (c = fmt; *c; c++) { | ||||
| 		if (*c == '%') { | ||||
| @@ -138,7 +139,7 @@ int print(char *fmt, ...) { | ||||
| } | ||||
|  | ||||
|  | ||||
| int print_func(void (*putc)(char), char *fmt, ...) { | ||||
| int print_func(int (*putc)(char), char *fmt, ...) { | ||||
| 	int ret; | ||||
| 	va_list arg; | ||||
|  | ||||
|   | ||||
| @@ -19,6 +19,7 @@ | ||||
|  */ | ||||
|  | ||||
| #include <atags.h> | ||||
| #include <init.h> | ||||
| #include <kmalloc.h> | ||||
| #include <mmu.h> | ||||
| #include <mm.h> | ||||
| @@ -26,13 +27,13 @@ | ||||
| #include <framebuffer.h> | ||||
| #include <console.h> | ||||
|  | ||||
| #include <drivers/serial.h> | ||||
|  | ||||
| #ifdef CONFIG_VEXPRESS_A9 | ||||
| #include <drivers/pl011.h> | ||||
| #include <drivers/pl111.h> | ||||
| #endif | ||||
|  | ||||
| #ifdef CONFIG_RPI | ||||
| #include <drivers/pi_mini_uart.h> | ||||
| #include <drivers/bcm2835_videocore.h> | ||||
| #endif | ||||
|  | ||||
| @@ -56,74 +57,11 @@ void video_init(void) { | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void test_mm() { | ||||
| 	struct page *p, *q; | ||||
| void serial_console_init() { | ||||
| 	struct serial_dev *sdev = serial_first_device(); | ||||
|  | ||||
| 	print("\ntest_mm():\n"); | ||||
|  | ||||
| 	p = mm_get_free_pages(0); | ||||
| 	if (p) | ||||
| 		print("%x, %x\n", p, p->address); | ||||
| 	else | ||||
| 		print("Error: failed to allocate memory for p\n"); | ||||
|  | ||||
| 	q = mm_get_free_pages(4); | ||||
| 	if (q) | ||||
| 		print("%x, %x\n", q, q->address); | ||||
| 	else | ||||
| 		print("Error: failed to allocate memory for q\n"); | ||||
|  | ||||
| 	mm_put_free_pages(p); | ||||
| 	mm_put_free_pages(q); | ||||
|  | ||||
| 	q = mm_get_free_pages(1); | ||||
| 	if (q) | ||||
| 		print("%x, %x\n", q, q->address); | ||||
| 	else | ||||
| 		print("Error: failed to allocate memory for q\n"); | ||||
|  | ||||
| 	p = mm_get_free_pages(0); | ||||
| 	if (p) | ||||
| 		print("%x, %x\n", p, p->address); | ||||
| 	else | ||||
| 		print("Error: failed to allocate memory for p\n"); | ||||
| 	mm_put_free_pages(p); | ||||
| 	mm_put_free_pages(q); | ||||
|  | ||||
| } | ||||
|  | ||||
| void test_kmalloc() { | ||||
| 	void *a, *b, *c, *d; | ||||
|  | ||||
| 	print("\ntest_kmalloc():\n"); | ||||
|  | ||||
| 	a = kmalloc(4); | ||||
| 	print("a: %x\n", a); | ||||
| 	b = kmalloc(13); | ||||
| 	print("b: %x\n", b); | ||||
| 	c = kmalloc(4); | ||||
| 	print("c: %x\n", c); | ||||
| 	d = kmalloc(25); | ||||
| 	print("d: %x\n", d); | ||||
|  | ||||
| 	kfree(c); | ||||
| 	kfree(b); | ||||
| 	kfree(a); | ||||
| 	kfree(d); | ||||
|  | ||||
| 	a = kmalloc(13); | ||||
| 	print("a: %x\n", a); | ||||
| 	b = kmalloc(4); | ||||
| 	print("b: %x\n", b); | ||||
| 	c = kmalloc(25); | ||||
| 	print("c: %x\n", c); | ||||
| 	d = kmalloc(7); | ||||
| 	print("d: %x\n", d); | ||||
| } | ||||
|  | ||||
| void test_memory() { | ||||
| 	test_mm(); | ||||
| 	test_kmalloc(); | ||||
| 	if (sdev) | ||||
| 		print_init(sdev->putc); | ||||
| } | ||||
|  | ||||
| void kmalloc_init(); | ||||
| @@ -135,14 +73,9 @@ int main(void) { | ||||
| 	//setup MMU | ||||
| 	mmu_reinit(); | ||||
|  | ||||
| 	//initialize the serial console | ||||
| #ifdef CONFIG_VEXPRESS_A9 | ||||
| 	print_init(&pl011_putc); | ||||
| #endif | ||||
| #ifdef CONFIG_RPI | ||||
| 	mini_uart_init(); | ||||
| 	print_init(&mini_uart_putc); | ||||
| #endif | ||||
| 	init_earlyinitcalls(); | ||||
|  | ||||
| 	serial_console_init(); | ||||
|  | ||||
| 	//setup memory | ||||
| 	mm_init(); | ||||
| @@ -159,7 +92,7 @@ int main(void) { | ||||
| 		declare_memory_region(lower, upper); | ||||
| 	} while (!atags_next_mem_region(&atags)); | ||||
|  | ||||
| 	test_memory(); | ||||
| 	init_initcalls(); | ||||
|  | ||||
| 	video_init(); | ||||
| 	console_init(&myfb); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user