diff --git a/Makefile b/Makefile index 2d05d21..94808cf 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,7 @@ KOBJS = include boot/Makefile.inc include kernel/Makefile.inc +include devices/Makefile.inc all: aedrix-kernel #all: diff --git a/devices/Makefile.inc b/devices/Makefile.inc new file mode 100644 index 0000000..24f4678 --- /dev/null +++ b/devices/Makefile.inc @@ -0,0 +1,4 @@ +DEVICES_PREFIX = devices + +KOBJS += $(DEVICES_PREFIX)/pl110.o +KOBJS += $(DEVICES_PREFIX)/pl011.o diff --git a/devices/pl011.c b/devices/pl011.c new file mode 100644 index 0000000..1a4c1a9 --- /dev/null +++ b/devices/pl011.c @@ -0,0 +1,13 @@ +#define PL011_SERIAL_BASE 0x16000000 +#define PL011_SERIAL_FLAG_REGISTER 0x18 +#define PL011_SERIAL_BUFFER_FULL (1 << 5) + +void pl011_putc(char c) +{ + /* Wait until the serial buffer is empty */ + while (*(volatile unsigned long*)(PL011_SERIAL_BASE + PL011_SERIAL_FLAG_REGISTER) + & (PL011_SERIAL_BUFFER_FULL)); + + /* When it's empty, put our character at the base */ + *(volatile unsigned long*)PL011_SERIAL_BASE = c; +} diff --git a/devices/pl110.c b/devices/pl110.c new file mode 100644 index 0000000..fd2adfa --- /dev/null +++ b/devices/pl110.c @@ -0,0 +1,55 @@ +#include + +typedef unsigned int uint32; + +#define PL110_CR_EN 0x001 +#define PL110_CR_PWR 0x800 +#define PL110_IOBASE 0xc0000000 +#define PL110_PALBASE (PL110_IOBASE + 0x200) +#define PL110_FB_BASE 0x200000; + +struct pl110_control { + uint32 volatile timing0; //0 + uint32 volatile timing1; //4 + uint32 volatile timing2; //8 + uint32 volatile timing3; //c + uint32 volatile upbase; //10 + uint32 volatile lpbase; //14 + uint32 volatile intrenable; //18 + uint32 volatile control; //1c +}; + +struct fbdev pl110_fb_device; + +int pl110_init(struct fb *f, unsigned int color_depth) { + struct pl110_control *plio = (struct pl110_control*)PL110_IOBASE; + + /* 640x480 pixels */ + plio->timing0 = 0x3f1f3f9c; + plio->timing1 = 0x080b61df; + plio->upbase = PL110_FB_BASE; + + if (color_depth == FB_COLOR_DEPTH_8) { + plio->control = 0x1827; + } else if (color_depth == FB_COLOR_DEPTH_16) { + plio->control = 0x1829; + } else if (color_depth == FB_COLOR_DEPTH_24) { + plio->control = 0x182B; + } else { + //assume 16 if nothing else fit + color_depth = 16; + plio->control = 0x1829; + } + + f->device = &pl110_fb_device; + f->device->fbaddr = (void*)PL110_FB_BASE; + f->width = 640; + f->device->pixelwidth = 640; + f->height = 480; + f->device->pixelheight = 480; + + f->color_depth = color_depth; + f->device->color_depth = color_depth; + + return 0; +} diff --git a/include/devices/pl011.h b/include/devices/pl011.h new file mode 100644 index 0000000..d96f2a9 --- /dev/null +++ b/include/devices/pl011.h @@ -0,0 +1,6 @@ +#ifndef PL011_H +#define PL011_H + +void pl011_putc(char c); + +#endif /* PL011_H */ diff --git a/include/devices/pl110.h b/include/devices/pl110.h new file mode 100644 index 0000000..47afb1c --- /dev/null +++ b/include/devices/pl110.h @@ -0,0 +1,3 @@ +#include + +int pl110_init(struct fb *f, unsigned int color_depth);