mirror of
https://github.com/drasko/codezero.git
synced 2026-01-11 18:33:16 +01:00
Merge branch 'rebase' of git://git.l4dev.org/~amit/codezero into amit
Conflicts: conts/baremetal/timer_service/main.c
This commit is contained in:
@@ -47,12 +47,12 @@ CONT%(cn)d_LINUX_ROOTFS_ADDRESS 'Container %(cn)d Linux ROOTFS Address'
|
||||
|
||||
default CONT%(cn)d_PAGER_LMA from CONT%(cn)d_PHYS0_START
|
||||
default CONT%(cn)d_PAGER_VMA from CONT%(cn)d_VIRT0_START
|
||||
default CONT%(cn)d_PAGER_SHM_START from 0x40000000
|
||||
default CONT%(cn)d_PAGER_SHM_END from 0x50000000
|
||||
default CONT%(cn)d_PAGER_TASK_START from 0x30000000
|
||||
default CONT%(cn)d_PAGER_TASK_END from 0x40000000
|
||||
default CONT%(cn)d_PAGER_UTCB_START from 0xf8100000
|
||||
default CONT%(cn)d_PAGER_UTCB_END from 0xf8200000
|
||||
default CONT%(cn)d_PAGER_SHM_START from CONT%(cn)d_VIRT1_START
|
||||
default CONT%(cn)d_PAGER_SHM_END from CONT%(cn)d_VIRT1_END
|
||||
default CONT%(cn)d_PAGER_TASK_START from CONT%(cn)d_VIRT2_START
|
||||
default CONT%(cn)d_PAGER_TASK_END from CONT%(cn)d_VIRT2_END
|
||||
default CONT%(cn)d_PAGER_UTCB_START from CONT%(cn)d_VIRT3_START
|
||||
default CONT%(cn)d_PAGER_UTCB_END from CONT%(cn)d_VIRT3_END
|
||||
default CONT%(cn)d_LINUX_ZRELADDR from (CONT%(cn)d_LINUX_PHYS_OFFSET + 0x8000)
|
||||
default CONT%(cn)d_LINUX_PAGE_OFFSET from CONT%(cn)d_VIRT0_START
|
||||
default CONT%(cn)d_LINUX_PHYS_OFFSET from CONT%(cn)d_PHYS0_START
|
||||
@@ -128,7 +128,16 @@ default CONT%(cn)d_VIRT4_END from (CONT%(cn)d_VIRT4_START + 0x10000000)
|
||||
default CONT%(cn)d_VIRT5_START from 0xe0000000
|
||||
default CONT%(cn)d_VIRT5_END from 0xf0000000
|
||||
|
||||
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")
|
||||
derive baremetal%(cn)d from
|
||||
(CONT%(cn)d_BAREMETAL_PROJ_EMPTY==y) ? "empty%(cn)d" :
|
||||
((CONT%(cn)d_BAREMETAL_PROJ_HELLO_WORLD==y) ? "hello_world%(cn)d" :
|
||||
((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_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")
|
||||
|
||||
when CONT%(cn)d_TYPE_LINUX==y suppress cont%(cn)d_default_pager_params
|
||||
unless CONT%(cn)d_TYPE_POSIX==y suppress cont%(cn)d_posix_pager_params
|
||||
@@ -152,22 +161,24 @@ cont%(cn)d_linux_pager_params 'Container %(cn)d Linux Pager Parameters'
|
||||
cont%(cn)d_default_pager_params 'Container %(cn)d Default Pager Parameters'
|
||||
cont%(cn)d_posix_pager_params 'Container %(cn)d POSIX Pager Parameters'
|
||||
|
||||
cont%(cn)d_baremetal_params 'Baremetal Project'
|
||||
CONT%(cn)d_BAREMETAL_PROJ0 'Empty Project'
|
||||
CONT%(cn)d_BAREMETAL_PROJ1 'Hello World'
|
||||
CONT%(cn)d_BAREMETAL_PROJ2 'Thread Library Demo'
|
||||
CONT%(cn)d_BAREMETAL_PROJ3 'Test Project'
|
||||
CONT%(cn)d_BAREMETAL_PROJ4 'UART Service'
|
||||
CONT%(cn)d_BAREMETAL_PROJ5 'Timer Service'
|
||||
cont%(cn)d_baremetal_params 'Baremetal Project'
|
||||
CONT%(cn)d_BAREMETAL_PROJ_EMPTY 'Empty Project'
|
||||
CONT%(cn)d_BAREMETAL_PROJ_HELLO_WORLD 'Hello World'
|
||||
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_PROJ0
|
||||
CONT%(cn)d_BAREMETAL_PROJ1
|
||||
CONT%(cn)d_BAREMETAL_PROJ2
|
||||
CONT%(cn)d_BAREMETAL_PROJ3
|
||||
CONT%(cn)d_BAREMETAL_PROJ4
|
||||
CONT%(cn)d_BAREMETAL_PROJ5
|
||||
default CONT%(cn)d_BAREMETAL_PROJ0
|
||||
CONT%(cn)d_BAREMETAL_PROJ_EMPTY
|
||||
CONT%(cn)d_BAREMETAL_PROJ_HELLO_WORLD
|
||||
CONT%(cn)d_BAREMETAL_PROJ_THREADS_DEMO
|
||||
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
|
||||
CONT%(cn)d_PAGER_LMA@
|
||||
@@ -223,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
|
||||
@@ -246,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
|
||||
|
||||
@@ -12,7 +12,6 @@ class Container:
|
||||
self.name = None
|
||||
self.type = None
|
||||
self.id = id
|
||||
self.baremetal_id = 0
|
||||
self.pager_lma = 0
|
||||
self.pager_vma = 0
|
||||
self.pager_size = 0
|
||||
@@ -131,10 +130,7 @@ class configuration:
|
||||
|
||||
# TODO: Carry this over to Container() as static method???
|
||||
def get_container_parameter(self, id, param, val):
|
||||
if param[:len("SOURCE_PATH")] == "SOURCE_PATH":
|
||||
parts = val.split("\"", 3)
|
||||
self.containers[id].src_path = parts[1]
|
||||
elif param[:len("PAGER_LMA")] == "PAGER_LMA":
|
||||
if param[:len("PAGER_LMA")] == "PAGER_LMA":
|
||||
self.containers[id].pager_lma = int(val, 0)
|
||||
elif param[:len("PAGER_VMA")] == "PAGER_VMA":
|
||||
self.containers[id].pager_vma = int(val, 0)
|
||||
@@ -173,12 +169,11 @@ class configuration:
|
||||
if regionid + 1 > self.containers[id].phys_regions:
|
||||
self.containers[id].phys_regions = regionid + 1
|
||||
elif param[:len("OPT_NAME")] == "OPT_NAME":
|
||||
dirname = val[1:-1].lower()
|
||||
self.containers[id].dirname = dirname
|
||||
self.containers[id].name = dirname
|
||||
elif param[:len("BAREMETAL_PROJ")] == "BAREMETAL_PROJ":
|
||||
param1 = param.split("_", 1)
|
||||
self.containers[id].baremetal_id = param1[1][-1:]
|
||||
name = val[1:-1].lower()
|
||||
self.containers[id].name = name
|
||||
elif param[:len("BAREMETAL_PROJ_")] == "BAREMETAL_PROJ_":
|
||||
param1 = param.split("_", 2)
|
||||
self.containers[id].dirname = param1[2].lower()
|
||||
elif param[:len("CAP_")] == "CAP_":
|
||||
prefix, param_rest = param.split('_', 1)
|
||||
prepare_capability(self.containers[id], param_rest, val)
|
||||
|
||||
67
conts/baremetal/clcd_service/SConstruct
Normal file
67
conts/baremetal/clcd_service/SConstruct
Normal 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')
|
||||
277
conts/baremetal/clcd_service/main.c
Normal file
277
conts/baremetal/clcd_service/main.c
Normal 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();
|
||||
}
|
||||
|
||||
36
conts/baremetal/timer_service/include/timer.h
Normal file
36
conts/baremetal/timer_service/include/timer.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef __TIMER_H__
|
||||
#define __TIMER_H__
|
||||
|
||||
/*
|
||||
* Timer specific things are here
|
||||
*/
|
||||
#include <l4lib/mutex.h>
|
||||
#include <l4/lib/list.h>
|
||||
|
||||
/*
|
||||
* Structure representing the sleeping tasks,
|
||||
* tgid: tgid of sleeping task
|
||||
* wait_count: time left, in microseconds, after which task
|
||||
* will be signalled to get out of sleep
|
||||
*/
|
||||
struct timer_task {
|
||||
struct link list;
|
||||
l4id_t tgid;
|
||||
unsigned int wait_count;
|
||||
};
|
||||
|
||||
/*
|
||||
* Timer structure,
|
||||
* base: base address of sp804 timer encapsulated
|
||||
* count: Count in microseconds from the start of this timer
|
||||
* tasklist: list of tasks sleeping for some value of count
|
||||
* lock: lock protecting the corruption of tasklist
|
||||
*/
|
||||
struct sp804_timer {
|
||||
unsigned int base;
|
||||
unsigned int count;
|
||||
struct link tasklist;
|
||||
struct l4_mutex lock;
|
||||
};
|
||||
|
||||
#endif /* __TIMER_H__ */
|
||||
@@ -9,11 +9,12 @@
|
||||
#include <l4/api/errno.h>
|
||||
|
||||
#include <l4/api/space.h>
|
||||
#include <malloc/malloc.h>
|
||||
#include <capability.h>
|
||||
#include <container.h>
|
||||
#include "sp804_timer.h"
|
||||
#include <linker.h>
|
||||
|
||||
#include <timer.h>
|
||||
|
||||
/* Frequency of timer in MHz */
|
||||
#define TIMER_FREQUENCY 1
|
||||
@@ -188,16 +189,36 @@ int timer_probe_devices(void)
|
||||
|
||||
static struct sp804_timer timer[TIMERS_TOTAL];
|
||||
|
||||
struct timer_task *get_timer_task(l4id_t tgid)
|
||||
{
|
||||
/* May be we can prepare a cache for timer_task structs */
|
||||
struct timer_task *task = (struct timer_task *)kzalloc(sizeof(struct timer_task));
|
||||
|
||||
link_init(&task->list);
|
||||
task->tgid = tgid;
|
||||
task->wait_count = timer[0].count;
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
void free_timer_task(struct timer_task *task)
|
||||
{
|
||||
kfree(task);
|
||||
}
|
||||
|
||||
int timer_setup_devices(void)
|
||||
{
|
||||
for (int i = 0; i < TIMERS_TOTAL; i++) {
|
||||
/* Get one page from address pool */
|
||||
timer[i].base = (unsigned long)l4_new_virtual(1);
|
||||
timer[i].count = 0;
|
||||
link_init(&timer[i].tasklist);
|
||||
l4_mutex_init(&timer[i].lock);
|
||||
|
||||
/* Map timers to a virtual address region */
|
||||
if (IS_ERR(l4_map((void *)__pfn_to_addr(timer_cap[i].start),
|
||||
(void *)timer[i].base, timer_cap[i].size, MAP_USR_IO_FLAGS,
|
||||
self_tid()))) {
|
||||
(void *)timer[i].base, timer_cap[i].size, MAP_USR_IO_FLAGS,
|
||||
self_tid()))) {
|
||||
printf("%s: FATAL: Failed to map TIMER device "
|
||||
"%d to a virtual address\n",
|
||||
__CONTAINER_NAME__,
|
||||
@@ -206,7 +227,7 @@ int timer_setup_devices(void)
|
||||
}
|
||||
|
||||
/* Initialise timer */
|
||||
sp804_init(timer[i].base, SP804_TIMER_RUNMODE_FREERUN, \
|
||||
sp804_init(timer[i].base, SP804_TIMER_RUNMODE_PERIODIC, \
|
||||
SP804_TIMER_WRAPMODE_WRAPPING, SP804_TIMER_WIDTH32BIT, \
|
||||
SP804_TIMER_IRQDISABLE);
|
||||
|
||||
@@ -264,18 +285,48 @@ void *l4_new_virtual(int npages)
|
||||
return address_new(&device_vaddr_pool, npages, PAGE_SIZE);
|
||||
}
|
||||
|
||||
int timer_gettime(int devno)
|
||||
void timer_irq_handler(void)
|
||||
{
|
||||
return sp804_read_value(timer[devno].base);
|
||||
struct timer_task *struct_ptr, *temp_ptr;
|
||||
|
||||
timer[0].count += 1;
|
||||
|
||||
/*
|
||||
* FIXME:
|
||||
* Traverse through the sleeping process list and
|
||||
* wake any process if required, we need to put this part in bottom half
|
||||
*/
|
||||
list_foreach_removable_struct(struct_ptr, temp_ptr, &timer[0].tasklist, list)
|
||||
if (struct_ptr->wait_count == timer[0].count) {
|
||||
|
||||
/* Remove task from list */
|
||||
l4_mutex_lock(&timer[0].lock);
|
||||
list_remove(&struct_ptr->list);
|
||||
l4_mutex_unlock(&timer[0].lock);
|
||||
|
||||
/* wake the sleeping process, send wake ipc */
|
||||
|
||||
free_timer_task(struct_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void timer_sleep(int sec)
|
||||
int timer_gettime(void)
|
||||
{
|
||||
/*
|
||||
* TODO: We need to have a timer struct already present to be used
|
||||
* as reference for us. to implement this call
|
||||
*/
|
||||
return timer[0].count;
|
||||
}
|
||||
|
||||
void timer_sleep(l4id_t tgid, int sec)
|
||||
{
|
||||
struct timer_task *task = get_timer_task(tgid);
|
||||
|
||||
/* Check for overflow */
|
||||
task->wait_count += (sec * 1000000);
|
||||
|
||||
l4_mutex_lock(&timer[0].lock);
|
||||
list_insert_tail(&task->list, &timer[0].tasklist);
|
||||
l4_mutex_unlock(&timer[0].lock);
|
||||
}
|
||||
|
||||
void handle_requests(void)
|
||||
{
|
||||
u32 mr[MR_UNUSED_TOTAL];
|
||||
@@ -311,11 +362,12 @@ void handle_requests(void)
|
||||
*/
|
||||
switch (tag) {
|
||||
case L4_IPC_TAG_TIMER_GETTIME:
|
||||
timer_gettime(1);
|
||||
mr[0] = timer_gettime();
|
||||
break;
|
||||
|
||||
case L4_IPC_TAG_TIMER_SLEEP:
|
||||
timer_sleep(mr[0]);
|
||||
timer_sleep(senderid, mr[0]);
|
||||
/* TODO: Halt the caller for mr[0] seconds */
|
||||
break;
|
||||
|
||||
default:
|
||||
21
conts/baremetal/uart_service/container.c
Normal file
21
conts/baremetal/uart_service/container.c
Normal 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();
|
||||
}
|
||||
|
||||
12
conts/baremetal/uart_service/include/capability.h
Normal file
12
conts/baremetal/uart_service/include/capability.h
Normal 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 */
|
||||
13
conts/baremetal/uart_service/include/container.h
Normal file
13
conts/baremetal/uart_service/include/container.h
Normal 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__ */
|
||||
7
conts/baremetal/uart_service/include/linker.h
Normal file
7
conts/baremetal/uart_service/include/linker.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef __LINKER_H__
|
||||
#define __LINKER_H__
|
||||
|
||||
extern char vma_start[];
|
||||
extern char __end[];
|
||||
|
||||
#endif /* __LINKER_H__ */
|
||||
@@ -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)
|
||||
|
||||
104
conts/libdev/clcd/pl110/include/pl110_clcd.h
Normal file
104
conts/libdev/clcd/pl110/include/pl110_clcd.h
Normal 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__ */
|
||||
68
conts/libdev/clcd/pl110/src/pl110_clcd.c
Normal file
68
conts/libdev/clcd/pl110/src/pl110_clcd.c
Normal 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));
|
||||
|
||||
}
|
||||
|
||||
@@ -56,10 +56,6 @@
|
||||
#define SP804_TIMERMIS 0x14
|
||||
#define SP804_TIMERBGLOAD 0x18
|
||||
|
||||
struct sp804_timer {
|
||||
unsigned int base;
|
||||
};
|
||||
|
||||
void sp804_init(unsigned int timer_base, int runmode, int wrapmode, \
|
||||
int width, int irq_enable);
|
||||
void sp804_irq_handler(unsigned int timer_base);
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#define setbit(bit, a) write(read(a) | bit, a)
|
||||
#define clrbit(bit, a) write(read(a) & ~bit, a)
|
||||
|
||||
extern void timer_irq_handler(void);
|
||||
|
||||
void sp804_irq_handler(unsigned int timer_base)
|
||||
{
|
||||
/*
|
||||
@@ -17,6 +19,7 @@ void sp804_irq_handler(unsigned int timer_base)
|
||||
* as it automatically reloads and wraps
|
||||
*/
|
||||
write(1, (timer_base + SP804_TIMERINTCLR));
|
||||
timer_irq_handler();
|
||||
}
|
||||
|
||||
static inline void sp804_control(unsigned int timer_base, int bit, int setclr)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -29,17 +29,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);
|
||||
|
||||
166
scripts/baremetal/baremetal_add_container.py
Executable file
166
scripts/baremetal/baremetal_add_container.py
Executable file
@@ -0,0 +1,166 @@
|
||||
#! /usr/bin/env python2.6
|
||||
# -*- mode: python; coding: utf-8; -*-
|
||||
#
|
||||
# Script to add/remove project to baremetal
|
||||
# menu of main screen
|
||||
#
|
||||
# This script should be called from project root directory
|
||||
#
|
||||
import os, sys, shutil, re
|
||||
|
||||
PROJRELROOT = '../../'
|
||||
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), PROJRELROOT)))
|
||||
|
||||
from optparse import OptionParser
|
||||
from os.path import join
|
||||
from shutil import copytree
|
||||
from config.projpaths import *
|
||||
|
||||
def parse_cmdline_options():
|
||||
usage = "usage: %prog [options] arg"
|
||||
parser = OptionParser(usage)
|
||||
|
||||
parser.add_option("-a", "--add", action = "store_true", default = False,
|
||||
dest = "addproject", help = "Add new project to baremetal projects")
|
||||
parser.add_option("-d", "--del", action = "store_true", default = False,
|
||||
dest = "delproject", help = "Delete existing project from baremetal projects")
|
||||
parser.add_option("-i", "--desc", type = "string", dest = "projdesc",
|
||||
help = "Description of new project to be added")
|
||||
parser.add_option("-s", "--src", type = "string", dest = "srcpath",
|
||||
help = "With -a, Source directory for new project to be added \
|
||||
With -d, Source directory of baremetal project to be deleted")
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
# Sanity checks
|
||||
if (not options.addproject and not options.delproject) or \
|
||||
(options.addproject and options.delproject):
|
||||
parser.error("Only one of -a or -d needed, use -h argument for help")
|
||||
exit()
|
||||
|
||||
if options.addproject:
|
||||
add_del = 1
|
||||
if not options.projdesc or not options.srcpath:
|
||||
parser.error("--desc or --src missing, use -h argument for help")
|
||||
exit()
|
||||
|
||||
if options.delproject:
|
||||
add_del = 0
|
||||
if options.projdesc or not options.srcpath:
|
||||
parser.error("--desc provided or --src missing with -d, use -h argument for help")
|
||||
exit()
|
||||
|
||||
return options.projdesc, options.srcpath, add_del
|
||||
|
||||
def container_cml_templ_del_symbl(projname):
|
||||
cont_templ = "config/cml/container_ruleset.template"
|
||||
sym = "CONT%(cn)d_BAREMETAL_PROJ_" + projname.upper()
|
||||
|
||||
buffer = ""
|
||||
with open(cont_templ, 'r') as fin:
|
||||
exist = False
|
||||
# Prepare buffer for new cont_templ with new project symbols added
|
||||
for line in fin:
|
||||
parts = line.split()
|
||||
|
||||
# Find out where baremetal symbols start in cont_templ
|
||||
if len(parts) > 1 and parts[0] == sym:
|
||||
exist = True
|
||||
continue
|
||||
elif len(parts) == 1 and parts[0] == sym:
|
||||
continue
|
||||
|
||||
buffer += line
|
||||
if exist == False:
|
||||
print "Baremetal project named " + projname + " does not exist"
|
||||
exit()
|
||||
|
||||
# Write new cont_templ
|
||||
with open(cont_templ, 'w+') as fout:
|
||||
fout.write(buffer)
|
||||
|
||||
|
||||
def container_cml_templ_add_symbl(projdesc, projname):
|
||||
cont_templ = "config/cml/container_ruleset.template"
|
||||
|
||||
pattern = re.compile("(CONT\%\(cn\)d_BAREMETAL_PROJ_)(.*)")
|
||||
baremetal_name_templ = "CONT%(cn)d_BAREMETAL_PROJ_"
|
||||
new_sym = baremetal_name_templ + projname.upper()
|
||||
|
||||
buffer = ""
|
||||
with open(cont_templ, 'r') as fin:
|
||||
baremetal_sym_found = False
|
||||
last_baremetal_proj = ""
|
||||
|
||||
# Prepare buffer for new cont_templ with new project symbols added
|
||||
for line in fin:
|
||||
parts = line.split()
|
||||
|
||||
# Find out where baremetal symbols start in cont_templ
|
||||
if len(parts) > 1 and re.match(pattern, parts[0]):
|
||||
baremetal_sym_found = True
|
||||
|
||||
# Find the name of last baremetal project already present in list
|
||||
last_baremetal_proj = parts[0][len(baremetal_name_templ):]
|
||||
|
||||
# We are done with baremetal symbols, add new symbol to buffer
|
||||
elif baremetal_sym_found == True:
|
||||
baremetal_sym_found = False
|
||||
sym_def = new_sym + "\t\'" + projdesc + "\'\n"
|
||||
buffer += sym_def
|
||||
|
||||
# Search for baremetal menu and add new project symbol
|
||||
elif len(parts) == 1 and \
|
||||
parts[0] == baremetal_name_templ + last_baremetal_proj:
|
||||
sym_reference = "\t" + new_sym + "\n"
|
||||
line += sym_reference
|
||||
|
||||
buffer += line
|
||||
|
||||
# Write new cont_templ
|
||||
with open(cont_templ, 'w+') as fout:
|
||||
fout.write(buffer)
|
||||
|
||||
def add_project(projdesc, srcdir, projname):
|
||||
container_cml_templ_add_symbl(projdesc, projname)
|
||||
|
||||
baremetal_dir = "conts/baremetal"
|
||||
dest_dir = join(baremetal_dir, projname)
|
||||
|
||||
print "Copying source files from " + srcdir + " to " + dest_dir
|
||||
shutil.copytree(srcdir, dest_dir)
|
||||
print "Done, New baremetal project " + projname + \
|
||||
" is ready to be used."
|
||||
|
||||
def del_project(srcdir, projname):
|
||||
container_cml_templ_del_symbl(projname)
|
||||
|
||||
baremetal_dir = "conts/baremetal"
|
||||
src_dir = join(baremetal_dir, projname)
|
||||
|
||||
print "Deleting source files from " + src_dir
|
||||
shutil.rmtree(src_dir, "ignore_errors")
|
||||
print "Done.."
|
||||
|
||||
def main():
|
||||
projdesc, srcdir, add_del = parse_cmdline_options()
|
||||
|
||||
# Get the base directory
|
||||
projpath, projname = os.path.split(srcdir)
|
||||
|
||||
# Python's basename() doesnot work fine if path ends with /,
|
||||
# so we need to manually correct this
|
||||
if projname == "":
|
||||
projpath, projname = os.path.split(projpath)
|
||||
|
||||
if add_del == 1:
|
||||
add_project(projdesc, srcdir, projname)
|
||||
else:
|
||||
del_project(srcdir, projname)
|
||||
|
||||
# Delete the config.cml file, so that user can see new projects
|
||||
os.system("rm -f " + CML2_CONFIG_FILE)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -49,8 +49,7 @@ class BaremetalContGenerator:
|
||||
|
||||
def create_baremetal_srctree(self, config, cont):
|
||||
# First, create the base project directory and sources
|
||||
str = 'baremetal' + cont.baremetal_id
|
||||
shutil.copytree(join(self.BAREMETAL_PROJ_SRC_DIR, str), self.CONT_SRC_DIR)
|
||||
shutil.copytree(join(self.BAREMETAL_PROJ_SRC_DIR, cont.dirname), self.CONT_SRC_DIR)
|
||||
|
||||
def copy_baremetal_build_desc(self, config, cont):
|
||||
id_header = '[Container ID]\n'
|
||||
@@ -114,7 +113,7 @@ class BaremetalContGenerator:
|
||||
for cont in config.containers:
|
||||
if cont.type == "baremetal":
|
||||
# Determine container directory name.
|
||||
self.CONT_SRC_DIR = join(self.BAREMETAL_SRC_BASEDIR, cont.dirname.lower())
|
||||
self.CONT_SRC_DIR = join(self.BAREMETAL_SRC_BASEDIR, cont.name.lower())
|
||||
self.build_readme_out = join(self.CONT_SRC_DIR, self.build_readme_name)
|
||||
self.build_desc_out = join(self.CONT_SRC_DIR, self.build_desc_name)
|
||||
self.linker_lds_out = join(join(self.CONT_SRC_DIR, 'include'), \
|
||||
@@ -122,7 +121,7 @@ class BaremetalContGenerator:
|
||||
self.container_h_out = join(join(self.CONT_SRC_DIR, 'include'), \
|
||||
self.container_h_name)
|
||||
|
||||
if not os.path.exists(join(self.BAREMETAL_SRC_BASEDIR, cont.dirname)):
|
||||
if not os.path.exists(join(self.BAREMETAL_SRC_BASEDIR, cont.name)):
|
||||
self.create_baremetal_sources(config, cont)
|
||||
else:
|
||||
# Don't create new sources but update configuration
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user