CLCD added as new capability, code note added yet

This commit is contained in:
Amit Mahajan
2009-12-04 00:54:23 +05:30
parent fcc1e52bea
commit 3d2b87d488
14 changed files with 604 additions and 5 deletions

View File

@@ -134,7 +134,8 @@ derive baremetal%(cn)d from
((CONT%(cn)d_BAREMETAL_PROJ_THREADS_DEMO==y) ? "thread_demo%(cn)d" :
((CONT%(cn)d_BAREMETAL_PROJ_TEST==y) ? "test%(cn)d" :
((CONT%(cn)d_BAREMETAL_PROJ_UART_SERVICE==y) ? "uart_service%(cn)d" :
((CONT%(cn)d_BAREMETAL_PROJ_TIMER_SERVICE==y) ? "timer_service%(cn)d" : "baremetal_noname%(cn)d" )))))
((CONT%(cn)d_BAREMETAL_PROJ_CLCD_SERVICE==y) ? "clcd_service%(cn)d" :
((CONT%(cn)d_BAREMETAL_PROJ_TIMER_SERVICE==y) ? "timer_service%(cn)d" : "baremetal_noname%(cn)d" ))))))
default CONT%(cn)d_OPT_NAME from (CONT%(cn)d_TYPE_LINUX==y) ? "linux%(cn)d" : ((CONT%(cn)d_TYPE_BAREMETAL==y) ? baremetal%(cn)d : "posix%(cn)d")
@@ -167,6 +168,7 @@ CONT%(cn)d_BAREMETAL_PROJ_THREADS_DEMO 'Thread Library Demo'
CONT%(cn)d_BAREMETAL_PROJ_TEST 'Test Project'
CONT%(cn)d_BAREMETAL_PROJ_UART_SERVICE 'UART Service'
CONT%(cn)d_BAREMETAL_PROJ_TIMER_SERVICE 'Timer Service'
CONT%(cn)d_BAREMETAL_PROJ_CLCD_SERVICE 'CLCD Service'
choices cont%(cn)d_baremetal_params
CONT%(cn)d_BAREMETAL_PROJ_EMPTY
@@ -175,6 +177,7 @@ choices cont%(cn)d_baremetal_params
CONT%(cn)d_BAREMETAL_PROJ_TEST
CONT%(cn)d_BAREMETAL_PROJ_UART_SERVICE
CONT%(cn)d_BAREMETAL_PROJ_TIMER_SERVICE
CONT%(cn)d_BAREMETAL_PROJ_CLCD_SERVICE
default CONT%(cn)d_BAREMETAL_PROJ_EMPTY
menu cont%(cn)d_default_pager_params
@@ -231,16 +234,19 @@ cont%(cn)d_cap_device_uart1 'Container %(cn)d UART1 Menu'
cont%(cn)d_cap_device_uart2 'Container %(cn)d UART2 Menu'
cont%(cn)d_cap_device_uart3 'Container %(cn)d UART3 Menu'
cont%(cn)d_cap_device_timer1 'Container %(cn)d TIMER23 Menu'
cont%(cn)d_cap_device_clcd 'Container %(cn)d CLCD Menu'
CONT%(cn)d_CAP_DEVICE_UART1_USE 'Container %(cn)d UART1 Enable'
CONT%(cn)d_CAP_DEVICE_UART2_USE 'Container %(cn)d UART2 Enable'
CONT%(cn)d_CAP_DEVICE_UART3_USE 'Container %(cn)d UART3 Enable'
CONT%(cn)d_CAP_DEVICE_TIMER1_USE 'Container %(cn)d TIMER23 Enable'
CONT%(cn)d_CAP_DEVICE_CLCD0_USE 'Container %(cn)d CLCD Enable'
default CONT%(cn)d_CAP_DEVICE_UART1_USE from n
default CONT%(cn)d_CAP_DEVICE_UART2_USE from n
default CONT%(cn)d_CAP_DEVICE_UART3_USE from n
default CONT%(cn)d_CAP_DEVICE_TIMER1_USE from n
default CONT%(cn)d_CAP_DEVICE_CLCD0_USE from n
menu cont%(cn)d_cap_device_uart1
CONT%(cn)d_CAP_DEVICE_UART1_USE
@@ -254,11 +260,15 @@ menu cont%(cn)d_cap_device_uart3
menu cont%(cn)d_cap_device_timer1
CONT%(cn)d_CAP_DEVICE_TIMER1_USE
menu cont%(cn)d_cap_device_clcd
CONT%(cn)d_CAP_DEVICE_CLCD0_USE
menu cont%(cn)d_device_list
cont%(cn)d_cap_device_uart1
cont%(cn)d_cap_device_uart2
cont%(cn)d_cap_device_uart3
cont%(cn)d_cap_device_timer1
cont%(cn)d_cap_device_clcd
#
# Settings for Custom Capabilities

View File

@@ -0,0 +1,67 @@
# -*- mode: python; coding: utf-8; -*-
#
# Codezero -- Virtualization microkernel for embedded systems.
#
# Copyright © 2009 B Labs Ltd
#
import os, shelve, sys
from os.path import *
PROJRELROOT = '../..'
sys.path.append(PROJRELROOT)
from config.projpaths import *
from config.configuration import *
config = configuration_retrieve()
platform = config.platform
arch = config.arch
gcc_cpu_flag = config.gcc_cpu_flag
LIBL4_RELDIR = 'conts/libl4'
KERNEL_INCLUDE = join(PROJROOT, 'include')
LIBL4_DIR = join(PROJROOT, LIBL4_RELDIR)
LIBL4_INCLUDE = join(LIBL4_DIR, 'include')
LIBL4_LIBPATH = join(BUILDDIR, LIBL4_RELDIR)
# Locally important paths are here
LIBC_RELDIR = 'conts/libc'
LIBC_DIR = join(PROJROOT, LIBC_RELDIR)
LIBC_LIBPATH = join(BUILDDIR, LIBC_RELDIR)
LIBC_INCLUDE = [join(LIBC_DIR, 'include'), \
join(LIBC_DIR, 'include/arch' + '/' + arch)]
LIBDEV_RELDIR = 'conts/libdev'
LIBDEV_DIR = join(PROJROOT, LIBDEV_RELDIR)
LIBDEV_LIBPATH = join(join(BUILDDIR, LIBDEV_RELDIR), 'sys-userspace')
LIBDEV_INCLUDE = [join(LIBDEV_DIR, 'uart/include'),
join(LIBDEV_DIR, 'clcd/pl110/include')]
LIBDEV_CCFLAGS = '-DPLATFORM_' + platform.upper()
# FIXME: Add these to autogenerated SConstruct !!!
LIBMEM_RELDIR = 'conts/libmem'
LIBMEM_DIR = join(PROJROOT, LIBMEM_RELDIR)
LIBMEM_LIBPATH = join(BUILDDIR, LIBMEM_RELDIR)
LIBMEM_INCLUDE = LIBMEM_DIR
env = Environment(CC = config.user_toolchain + 'gcc',
# We don't use -nostdinc because sometimes we need standard headers,
# such as stdarg.h e.g. for variable args, as in printk().
CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', \
'-Werror', ('-mcpu=' + gcc_cpu_flag), LIBDEV_CCFLAGS],
LINKFLAGS = ['-nostdlib', '-T' + "include/linker.lds", "-u_start"],
ASFLAGS = ['-D__ASSEMBLY__'], \
PROGSUFFIX = '.elf', # The suffix to use for final executable\
ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path\
LIBS = ['gcc', 'libl4', 'libmalloc', 'c-userspace', 'libdev-userspace', 'gcc', 'c-userspace'], # libgcc.a - This is required for division routines.
CPPPATH = ["#include", KERNEL_INCLUDE, LIBL4_INCLUDE, LIBDEV_INCLUDE, LIBC_INCLUDE, LIBMEM_INCLUDE],
LIBPATH = [LIBL4_LIBPATH, LIBDEV_LIBPATH, LIBC_LIBPATH, LIBMEM_LIBPATH],
CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h')
src = Glob('*.[cS]')
src += Glob('src/*.[cS]')
objs = env.Object(src)
prog = env.Program('main.elf', objs)
Depends(prog, 'include/linker.lds')

View File

@@ -0,0 +1,21 @@
/*
* Container entry point for pager
*
* Copyright (C) 2007-2009 B Labs Ltd.
*/
#include <l4lib/init.h>
#include <l4lib/utcb.h>
extern void main(void);
void __container_init(void)
{
/* Generic L4 initialisation */
__l4_init();
/* Entry to main */
main();
}

View File

@@ -0,0 +1,12 @@
#ifndef __UART_SERVICE_CAPABILITY_H__
#define __UART_SERVICE_CAPABILITY_H__
#include <l4lib/capability.h>
#include <l4/api/capability.h>
#include <l4/generic/cap-types.h>
void cap_print(struct capability *cap);
void cap_list_print(struct cap_list *cap_list);
int cap_read_all();
#endif /* header */

View File

@@ -0,0 +1,13 @@
/*
* Autogenerated definitions for this container.
*/
#ifndef __CONTAINER_H__
#define __CONTAINER_H__
#define __CONTAINER_NAME__ "uart_service"
#define __CONTAINER_ID__ 0
#define __CONTAINER__ "cont0"
#endif /* __CONTAINER_H__ */

View File

@@ -0,0 +1,7 @@
#ifndef __LINKER_H__
#define __LINKER_H__
extern char vma_start[];
extern char __end[];
#endif /* __LINKER_H__ */

View File

@@ -0,0 +1,277 @@
/*
* CLCD service for userspace
*/
#include <l4lib/arch/syslib.h>
#include <l4lib/arch/syscalls.h>
#include <l4lib/addr.h>
#include <l4lib/exregs.h>
#include <l4lib/ipcdefs.h>
#include <l4/api/errno.h>
#include <l4/api/space.h>
#include <capability.h>
#include <container.h>
#include <pl110_clcd.h> /* FIXME: Its best if this is <libdev/uart/pl011.h> */
#include <linker.h>
#define CLCD_TOTAL 1
static struct capability caparray[32];
static int total_caps = 0;
struct capability clcd_cap[CLCD_TOTAL];
int cap_read_all()
{
int ncaps;
int err;
/* Read number of capabilities */
if ((err = l4_capability_control(CAP_CONTROL_NCAPS,
0, 0, 0, &ncaps)) < 0) {
printf("l4_capability_control() reading # of"
" capabilities failed.\n Could not "
"complete CAP_CONTROL_NCAPS request.\n");
BUG();
}
total_caps = ncaps;
/* Read all capabilities */
if ((err = l4_capability_control(CAP_CONTROL_READ,
0, 0, 0, caparray)) < 0) {
printf("l4_capability_control() reading of "
"capabilities failed.\n Could not "
"complete CAP_CONTROL_READ_CAPS request.\n");
BUG();
}
return 0;
}
/*
* Scans for up to CLCD_TOTAL clcd devices in capabilities.
*/
int clcd_probe_devices(void)
{
int clcds = 0;
/* Scan for clcd devices */
for (int i = 0; i < total_caps; i++) {
/* Match device type */
if (cap_devtype(&caparray[i]) == CAP_DEVTYPE_CLCD) {
/* Copy to correct device index */
memcpy(&clcd_cap[cap_devnum(&caparray[i])],
&caparray[i], sizeof(clcd_cap[0]));
clcds++;
}
}
if (clcds != CLCD_TOTAL) {
printf("%s: Error, not all clcd could be found. "
"total clcds=%d\n", __CONTAINER_NAME__, clcds);
return -ENODEV;
}
return 0;
}
/*
* 1MB frame buffer,
* FIXME: can we do dma in this buffer?
*/
#define CLCD_FRAMEBUFFER_SZ 0x100000
static char framebuffer[CLCD_FRAMEBUFFER_SZ];
static struct pl110_clcd clcd[CLCD_TOTAL];
int clcd_setup_devices(void)
{
for (int i = 0; i < CLCD_TOTAL; i++) {
/* Get one page from address pool */
clcd[i].virt_base = (unsigned long)l4_new_virtual(1);
/* Map clcd to a virtual address region */
if (IS_ERR(l4_map((void *)__pfn_to_addr(clcd_cap[i].start),
(void *)clcd[i].virt_base, clcd_cap[i].size,
MAP_USR_IO_FLAGS,
self_tid()))) {
printf("%s: FATAL: Failed to map CLCD device "
"%d to a virtual address\n",
__CONTAINER_NAME__,
cap_devnum(&clcd_cap[i]));
BUG();
}
/* Initialize clcd */
pl110_initialise(&clcd[i], framebuffer);
}
return 0;
}
static struct address_pool device_vaddr_pool;
/*
* Initialize a virtual address pool
* for mapping physical devices.
*/
void init_vaddr_pool(void)
{
for (int i = 0; i < total_caps; i++) {
/* Find the virtual memory region for this process */
if (cap_type(&caparray[i]) == CAP_TYPE_MAP_VIRTMEM &&
__pfn_to_addr(caparray[i].start) ==
(unsigned long)vma_start) {
/*
* Do we have any unused virtual space
* where we run, and do we have enough
* pages of it to map all clcd?
*/
if (__pfn(page_align_up(__end))
+ CLCD_TOTAL <= caparray[i].end) {
/*
* Yes. We initialize the device
* virtual memory pool here.
*
* We may allocate virtual memory
* addresses from this pool.
*/
address_pool_init(&device_vaddr_pool,
page_align_up(__end),
__pfn_to_addr(caparray[i].end),
CLCD_TOTAL);
return;
} else
goto out_err;
}
}
out_err:
printf("%s: FATAL: No virtual memory "
"region available to map "
"devices.\n", __CONTAINER_NAME__);
BUG();
}
void *l4_new_virtual(int npages)
{
return address_new(&device_vaddr_pool, npages, PAGE_SIZE);
}
void handle_requests(void)
{
u32 mr[MR_UNUSED_TOTAL];
l4id_t senderid;
u32 tag;
int ret;
printf("%s: Initiating ipc.\n", __CONTAINER__);
if ((ret = l4_receive(L4_ANYTHREAD)) < 0) {
printf("%s: %s: IPC Error: %d. Quitting...\n",
__CONTAINER__, __FUNCTION__, ret);
BUG();
}
/* Syslib conventional ipc data which uses first few mrs. */
tag = l4_get_tag();
senderid = l4_get_sender();
/* Read mrs not used by syslib */
for (int i = 0; i < MR_UNUSED_TOTAL; i++)
mr[i] = read_mr(MR_UNUSED_START + i);
/*
* TODO:
*
* Maybe add tags here that handle requests for sharing
* of the requested cld device with the client?
*
* In order to be able to do that, we should have a
* shareable/grantable capability to the device. Also
* the request should (currently) come from a task
* inside the current container
*/
/*
* FIXME: Right now we are talking to CLCD by default, we need to define protocol
* for sommunication with CLCD service
*/
switch (tag) {
default:
printf("%s: Error received ipc from 0x%x residing "
"in container %x with an unrecognized tag: "
"0x%x\n", __CONTAINER__, senderid,
__cid(senderid), tag);
}
/* Reply */
if ((ret = l4_ipc_return(ret)) < 0) {
printf("%s: IPC return error: %d.\n", __FUNCTION__, ret);
BUG();
}
}
/*
* UTCB-size aligned utcb.
*
* BIG WARNING NOTE:
* This in-place declaration is legal if we are running
* in a disjoint virtual address space, where the utcb
* declaration lies in a unique virtual address in
* the system.
*/
#define DECLARE_UTCB(name) \
struct utcb name ALIGN(sizeof(struct utcb))
DECLARE_UTCB(utcb);
/* Set up own utcb for ipc */
int l4_utcb_setup(void *utcb_address)
{
struct task_ids ids;
struct exregs_data exregs;
int err;
l4_getid(&ids);
/* Clear utcb */
memset(utcb_address, 0, sizeof(struct utcb));
/* Setup exregs for utcb request */
memset(&exregs, 0, sizeof(exregs));
exregs_set_utcb(&exregs, (unsigned long)utcb_address);
if ((err = l4_exchange_registers(&exregs, ids.tid)) < 0)
return err;
return 0;
}
void main(void)
{
int err;
/* Read all capabilities */
cap_read_all();
/* Scan for clcd devices in capabilities */
clcd_probe_devices();
/* Initialize virtual address pool for clcds */
init_vaddr_pool();
/* Map and initialize clcd devices */
clcd_setup_devices();
/* Setup own utcb */
if ((err = l4_utcb_setup(&utcb)) < 0) {
printf("FATAL: Could not set up own utcb. "
"err=%d\n", err);
BUG();
}
/* Listen for clcd requests */
while (1)
handle_requests();
}

View File

View File

@@ -24,13 +24,18 @@ LIBDEV_UART_PATH = join(PROJROOT, 'conts/libdev/uart')
# Path for timer files
LIBDEV_TIEMR_PATH = join(PROJROOT, 'conts/libdev/timer/sp804')
# Path for clcd files
LIBDEV_CLCD_PATH = join(PROJROOT, 'conts/libdev/clcd/pl110')
e = env.Clone()
e.Append(CPPPATH = [LIBDEV_UART_PATH + '/include', LIBDEV_TIEMR_PATH + '/include'],
e.Append(CPPPATH = [LIBDEV_UART_PATH + '/include', LIBDEV_TIEMR_PATH + '/include',
LIBDEV_CLCD_PATH + '/include',],
CCFLAGS = ['-nostdinc', '-DVARIANT_' + variant.upper(),
'-DPLATFORM_' + platform.upper()])
source = Glob('uart/src' + '/*.c') + \
Glob('timer/sp804/src' + '/*.c')
Glob('timer/sp804/src' + '/*.c') + \
Glob('clcd/pl110/src' + '/*.c')
objects = e.StaticObject(source)
library = e.StaticLibrary('libdev-' + variant, objects)

View File

@@ -0,0 +1,104 @@
#ifndef __PL110_CLCD_H__
#define __PL110_CLCD_H__
/* Register offsets */
#define PL110_CLCD_TIMING0 0x000 /* Horizontal Axis Panel Control*/
#define PL110_CLCD_TIMING1 0x004 /* Vertical Axis Panel Control */
#define PL110_CLCD_TIMING2 0x008 /* Clock and Polarity Signal Control*/
#define PL110_CLCD_TIMING3 0x00c /* Line End Control */
#define PL110_CLCD_UPBASE 0x010 /* Upper Panel Frame Base Address*/
#define PL110_CLCD_LPBASE 0x014 /* Lower Panel Frame Base Address */
#define PL110_CLCD_IMSC 0x018 /* Interrupt Mast Set Clear */
#define PL110_CLCD_CONTROL 0x01c /* CLCD Control */
#define PL110_CLCD_RIS 0x020 /* Raw Interrupt Status */
#define PL110_CLCD_MIS 0x024 /* Masked Interrupt Status */
#define PL110_CLCD_ICR 0x028 /* Interrupt Clear */
#define PL110_CLCD_UPCURR 0x02c /* Upper Panel Current Address Value */
#define PL110_CLCD_LPCURR 0x030 /* Lower Panel Current Address Value */
//#define PL110_LCD_PALETTE
#define PL110_CLCD_PERIPHID0 0xfe0 /* Peripheral Identification */
#define PL110_CLCD_PERIPHID1 0xfe4 /* Peripheral Identification */
#define PL110_CLCD_PERIPHID2 0xfe8 /* Peripheral Identification */
#define PL110_CLCD_PERIPHID3 0xfec /* Peripheral Identification */
#define PL110_CLCD_PCELLID0 0xff0 /* Peripheral Identification */
#define PL110_CLCD_PCELLID1 0xff4 /* PrimeCell Identification */
#define PL110_CLCD_PCELLID2 0xff8 /* PrimeCell Identification */
#define PL110_CLCD_PCELLID3 0xffc /* PrimeCell Identification */
/* Scan mode */
#define SCAN_VMODE_NONINTERLACED 0 /* non interlaced */
#define SCAN_VMODE_INTERLACED 1 /* interlaced */
#define SCAN_VMODE_DOUBLE 2 /* double scan */
#define SCAN_VMODE_ODD_FLD_FIRST 4 /* interlaced: top line first */
#define SCAN_VMODE_MASK 255
/* Control Register Bits */
#define PL110_CNTL_LCDEN (1 << 0)
#define PL110_CNTL_LCDBPP1 (0 << 1)
#define PL110_CNTL_LCDBPP2 (1 << 1)
#define PL110_CNTL_LCDBPP4 (2 << 1)
#define PL110_CNTL_LCDBPP8 (3 << 1)
#define PL110_CNTL_LCDBPP16 (4 << 1)
#define PL110_CNTL_LCDBPP16_565 (6 << 1)
#define PL110_CNTL_LCDBPP24 (5 << 1)
#define PL110_CNTL_LCDBW (1 << 4)
#define PL110_CNTL_LCDTFT (1 << 5)
#define PL110_CNTL_LCDMONO8 (1 << 6)
#define PL110_CNTL_LCDDUAL (1 << 7)
#define PL110_CNTL_BGR (1 << 8)
#define PL110_CNTL_BEBO (1 << 9)
#define PL110_CNTL_BEPO (1 << 10)
#define PL110_CNTL_LCDPWR (1 << 11)
#define PL110_CNTL_LCDVCOMP(x) ((x) << 12)
#define PL110_CNTL_LDMAFIFOTIME (1 << 15)
#define PL110_CNTL_WATERMARK (1 << 16)
#define PL110_TIM2_CLKSEL (1 << 5)
#define PL110_TIM2_IVS (1 << 11)
#define PL110_TIM2_IHS (1 << 12)
#define PL110_TIM2_IPC (1 << 13)
#define PL110_TIM2_IOE (1 << 14)
#define PL110_TIM2_BCD (1 << 26)
struct videomode {
const char *name; /* optional */
unsigned int refresh; /* optional */
unsigned int xres;
unsigned int yres;
unsigned int pixclock;
unsigned int left_margin;
unsigned int right_margin;
unsigned int upper_margin;
unsigned int lower_margin;
unsigned int hsync_len;
unsigned int vsync_len;
unsigned int sync;
unsigned int vmode;
unsigned int flag;
};
struct pl110_clcd_panel {
struct videomode mode;
signed short width; /* width in mm */
signed short height; /* height in mm */
unsigned int tim2;
unsigned int tim3;
unsigned int cntl;
unsigned int bpp:8,
fixedtimings:1,
grayscale:1;
unsigned int connector;
};
struct pl110_clcd {
unsigned int virt_base;
struct pl110_clcd_panel *panel;
char *frame_buffer;
};
void pl110_initialise(struct pl110_clcd *clcd, char *buf);
#endif /* __PL110_CLCD_H__ */

View File

@@ -0,0 +1,68 @@
#include <pl110_clcd.h>
#define read(a) *((volatile unsigned int *)(a))
#define write(v, a) (*((volatile unsigned int *)(a)) = v)
#define setbit(bit, a) write(read(a) | bit, a)
#define clrbit(bit, a) write(read(a) & ~bit, a)
/*
* Default panel, we will use this for now
* Seems like qemu has support for this
*/
static struct pl110_clcd_panel vga = {
.mode = {
.name = "VGA",
.refresh = 60,
.xres = 640,
.yres = 480,
.pixclock = 39721,
.left_margin = 40,
.right_margin = 24,
.upper_margin = 32,
.lower_margin = 11,
.hsync_len = 96,
.vsync_len = 2,
.sync = 0,
.vmode = SCAN_VMODE_NONINTERLACED,
},
.width = -1,
.height = -1,
.tim2 = PL110_TIM2_BCD | PL110_TIM2_IPC,
.cntl = PL110_CNTL_LCDTFT | PL110_CNTL_LCDVCOMP(1),
.bpp = 16,
};
static void pl110_clcd_set_uppanel_fb(unsigned int clcd_base,
unsigned int fb_base)
{
write(fb_base, (clcd_base + PL110_CLCD_UPBASE));
}
#if 0
static void pl110_clcd_set_lwrpanel_fb(unsigned int clcd_base, unsigned int fb_base)
{
write(fb_base, (clcd_base +PL110_CLCD_LPBASE));
}
static unsigned int pl110_clcd_get_uppanel_fb(unsigned int clcd_base)
{
return read((clcd_base +PL110_CLCD_UPBASE));
}
static unsigned int pl110_clcd_get_lwrpanel_fb(unsigned int clcd_base)
{
return read((clcd_base +PL110_CLCD_LPBASE));
}
#endif
void pl110_initialise(struct pl110_clcd *clcd, char *buf)
{
clcd->panel = &vga;
clcd->frame_buffer = buf;
pl110_clcd_set_uppanel_fb(clcd->virt_base, (unsigned int)(buf));
}

View File

@@ -24,6 +24,7 @@
#define PB926_UART1_BASE 0x101F2000 /* Console port (UART1) */
#define PB926_UART2_BASE 0x101F3000 /* Console port (UART2) */
#define PB926_UART3_BASE 0x10009000 /* Console port (UART3) */
#define PB926_CLCD_BASE 0x10120000 /* Color LCD */
/*
* Uart virtual address until a file-based console access

View File

@@ -28,17 +28,21 @@
#define PB926_UART_SIZE 0x1000
#define PB926_TIMER_SIZE 0x1000
#define PB926_CLCD_SIZE 0x1000
#define PLATFORM_UART1_BASE PB926_UART1_BASE
#define PLATFORM_UART2_BASE PB926_UART2_BASE
#define PLATFORM_UART3_BASE PB926_UART3_BASE
#define PLATFORM_UART1_SIZE PB926_UART_SIZE
#define PLATFORM_UART2_SIZE PB926_UART_SIZE
#define PLATFORM_UART3_SIZE PB926_UART_SIZE
#define PLATFORM_TIMER1_BASE PB926_TIMER23_BASE
#define PLATFORM_TIMER1_SIZE PB926_TIMER_SIZE
#define PLATFORM_CLCD0_BASE PB926_CLCD_BASE
#define PLATFORM_CLCD0_SIZE PB926_CLCD_SIZE
int platform_setup_device_caps(struct kernel_resources *kres);
void platform_irq_enable(int irq);
void platform_irq_disable(int irq);

View File

@@ -26,7 +26,7 @@
*/
int platform_setup_device_caps(struct kernel_resources *kres)
{
struct capability *uart[4], *timer[4];
struct capability *uart[4], *timer[4], *clcd[1];
/* Setup capabilities for userspace uarts and timers */
uart[1] = alloc_bootmem(sizeof(*uart[1]), 0);
@@ -66,6 +66,16 @@ int platform_setup_device_caps(struct kernel_resources *kres)
link_init(&timer[1]->list);
cap_list_insert(timer[1], &kres->devmem_free);
/* Setup clcd capability as free */
clcd[0] = alloc_bootmem(sizeof(*clcd[0]), 0);
clcd[0]->start = __pfn(PB926_CLCD_BASE);
clcd[0]->end = clcd[0]->start + 1;
clcd[0]->size = clcd[0]->end - clcd[0]->start;
cap_set_devtype(clcd[0], CAP_DEVTYPE_CLCD);
cap_set_devnum(clcd[0], 0);
link_init(&clcd[0]->list);
cap_list_insert(clcd[0], &kres->devmem_free);
return 0;
}