diff --git a/devices/bcm2835_mailbox.c b/devices/bcm2835_mailbox.c new file mode 100644 index 0000000..a7e2e9b --- /dev/null +++ b/devices/bcm2835_mailbox.c @@ -0,0 +1,69 @@ +/* + Copyright (C) 2012, Aaron Lindsay + + 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 + +/* Mailbox Memory-Mapped Registers */ +#define VC_MMU_IO_OFFSET(addr) (addr - 0x7E000000 + 0x20000000) + +#define MBOX0_READ VC_MMU_IO_OFFSET(0x7E00B880) +/* MBOX0_READ layout: + 31-4 data The 28 bits of data sent to the CPU + 3-0 channel The mailbox channel number from which the data originated */ +#define MBOX0_PEEK VC_MMU_IO_OFFSET(0x7E00B890) //Read from the mailbox without removing data from it. +#define MBOX0_SENDER VC_MMU_IO_OFFSET(0x7E00B894) //Sender ID (bottom 2 bits only) +#define MBOX0_STATUS VC_MMU_IO_OFFSET(0x7E00B898) +/* MBOX0_STATUS layout: + 31 full Set if the mailbox is full, and thus no more data can be written to it. + 30 empty Set if the mailbox is empty, and thus no more data is available to be read from it. + 29-0 unused? */ +#define MBOX0_CONFIG VC_MMU_IO_OFFSET(0x7E00B89C) +#define MBOX0_WRITE VC_MMU_IO_OFFSET(0x7E00B8A0) //also MBOX1_READ? +/* MBOX0_WRITE layout: + 31-4 data The 28 bits of data to be sent + 3-0 channel The mailbox channel to send data to */ + +#define MBOX0_STATUS_FULL 0x80000000 +#define MBOX0_STATUS_EMPTY 0x40000000 + + +uint32 mailbox_read(uint32 channel) { + uint32 mbox_msg; + while (1) { + int i; + for (i = 0; *(volatile uint32 *)MBOX0_STATUS & MBOX0_STATUS_EMPTY; i++) { + if (i >= 1<<20) + return 0xFFFFFFFF; + } + + mbox_msg = *(volatile uint32 *)MBOX0_READ; + if ((mbox_msg & 0xf) == channel) + return mbox_msg & ~0xf; + } +} + +void mailbox_write(uint32 channel, uint32 data) { + channel &= 0xf; + data &= ~0xf; + + while (*(volatile uint32 *)MBOX0_STATUS & MBOX0_STATUS_FULL); + + *(volatile uint32 *)MBOX0_WRITE = channel | data; +} diff --git a/devices/bcm2835_videocore.c b/devices/bcm2835_videocore.c new file mode 100644 index 0000000..2847137 --- /dev/null +++ b/devices/bcm2835_videocore.c @@ -0,0 +1,94 @@ +/* + Copyright (C) 2012, Aaron Lindsay + + 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 +#include +#include +#include +#include + +struct bcm2835_config { + uint32 width; + uint32 height; + uint32 vwidth; + uint32 vheight; + uint32 pitch; + uint32 color_depth; + uint32 xoffset; + uint32 yoffset; + uint32 fb_base_addr; + uint32 size; +}; + +#define MAILBOX_BUFFER_SIZE (32*4*2) +#define FB_WIDTH 1024 +#define FB_HEIGHT 768 + +struct fbdev bcm2835_fb_device; + +int bcm2835_videocore_init(struct fb *f, unsigned int color_depth) { + struct bcm2835_config *cfg; + uint32 result; + void *mailbox_buffer_orig, *mailbox_buffer; + + if (!(mailbox_buffer_orig = kmalloc(MAILBOX_BUFFER_SIZE))) { + return -1; + } + + /* Round mailbox buffer to multiple of 0x10 because the low 4 bits of + the mailbox are used to send the channel, and therefore can't hold the low 4 + bits of the address */ + if ((uint32)mailbox_buffer_orig & 0xf) + mailbox_buffer = (void *)((uint32)mailbox_buffer_orig & ~0xf) + 0x10; + else + mailbox_buffer = mailbox_buffer_orig; + + cfg = (struct bcm2835_config *)mailbox_buffer; + cfg->width = FB_WIDTH; + cfg->height = FB_HEIGHT; + cfg->vwidth = FB_WIDTH; + cfg->vheight = FB_HEIGHT; + cfg->pitch = 0; + cfg->color_depth = color_depth; + cfg->xoffset = 0; + cfg->yoffset = 0; + cfg->fb_base_addr = 0; + cfg->size = 0; + + mailbox_write(MBOX_FB, (uint32)cfg); + result = mailbox_read(MBOX_FB); + + if (result || !cfg->fb_base_addr) { + print("Error: did not request a proper framebuffer\n"); + return -1; + } + + f->device = &bcm2835_fb_device; + f->device->fbaddr = (void*)cfg->fb_base_addr; + f->width = cfg->width; + f->device->pixelwidth = cfg->width; + f->height = cfg->height; + f->device->pixelheight = cfg->height; + + f->color_depth = color_depth; + f->device->color_depth = color_depth; + + return 0; +} diff --git a/devices/kernel.mk b/devices/kernel.mk index 8707352..3aded10 100644 --- a/devices/kernel.mk +++ b/devices/kernel.mk @@ -6,7 +6,9 @@ include $(BASEDIR)/header.mk OBJS_$(d) := $(d)/pl011.o \ $(d)/pl110.o \ $(d)/pl111.o \ - $(d)/pi_mini_uart.o + $(d)/pi_mini_uart.o \ + $(d)/bcm2835_mailbox.o \ + $(d)/bcm2835_videocore.o KOBJS += $(OBJS_$(d)) diff --git a/include/devices/bcm2835_mailbox.h b/include/devices/bcm2835_mailbox.h new file mode 100644 index 0000000..ad31021 --- /dev/null +++ b/include/devices/bcm2835_mailbox.h @@ -0,0 +1,38 @@ +/* + Copyright (C) 2012, Aaron Lindsay + + 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. + */ + +#ifndef BCM2835_MAILBOX_H +#define BCM2835_MAILBOX_H + +#include + +/* BCM2835 Mailbox Channels */ +#define MBOX_PM 0 //Power management interface +#define MBOX_FB 1 //Framebuffer +#define MBOX_VUART 2 //Virtual UART +#define MBOX_YCHIQ 3 //VCHIQ interface +#define MBOX_LEDS 4 //LEDs interface +#define MBOX_BUTTONS 5 //Buttons interface +#define MBOX_TOUCHSCRN 6 //Touch screen interface + +uint32 mailbox_read(uint32 channel); +void mailbox_write(uint32 channel, uint32 data); + +#endif /* BCM2835_MAILBOX_H */ diff --git a/include/devices/bcm2835_videocore.h b/include/devices/bcm2835_videocore.h new file mode 100644 index 0000000..d853090 --- /dev/null +++ b/include/devices/bcm2835_videocore.h @@ -0,0 +1,28 @@ +/* + Copyright (C) 2012, Aaron Lindsay + + 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 + +#ifndef BCM2835_VIDEOCORE_H +#define BCM2835_VIDEOCORE_H + +int bcm2835_videocore_init(struct fb *f, unsigned int color_depth); + +#endif /* BCM2835_VIDEOCORE_H */ diff --git a/kernel/start_kernel.c b/kernel/start_kernel.c index b455fc8..3a6ebba 100644 --- a/kernel/start_kernel.c +++ b/kernel/start_kernel.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include @@ -33,10 +33,10 @@ struct fb myfb; void video(void) { unsigned int x, y; - pl111_init(&myfb, 24); - x = 0, y = 0; - for (y=0; y<480; y++) - for (x=0; x<640; x++) + bcm2835_videocore_init(&myfb, 16); + + for (y = 0; y < myfb.height; y++) + for (x = 0; x < myfb.width; x++) fb_write_pixel(&myfb, x, y, 0x3f, 0x0, 0x6f); console_init(&myfb);