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