From a41caeebd2e60eca1088e760710d16f4751bfc7c Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Thu, 27 Aug 2009 12:00:04 +0300 Subject: [PATCH] Created libc under containers/posix which now all tasks use to build. There is a problem in the new libc that test0 now misbehaves. Going to be fixed. --- SConstruct | 19 +- containers/posix/fs0/SConscript | 2 +- containers/posix/fs0/include/lib/malloc.h | 6 + containers/posix/fs0/include/linker.lds | 2 +- containers/posix/fs0/include/vfs.h | 2 +- containers/posix/fs0/main.c | 2 +- containers/posix/fs0/src/crt0.S | 12 + containers/posix/fs0/src/file.c | 2 +- containers/posix/fs0/src/lib/bit.c | 2 +- containers/posix/fs0/src/lib/idpool.c | 2 +- containers/posix/fs0/src/lib/malloc.c | 3 +- containers/posix/fs0/src/lib/vaddr.c | 2 +- containers/posix/fs0/src/memfs/memfs.c | 2 +- containers/posix/libc/SConscript | 31 + .../posix/{mm0/src => libc/include}/arch | 0 .../posix/libc/include/arch-arm/pl011_uart.h | 407 +++++++++++++ .../posix/libc/include/arch-arm/stdint.h | 92 +++ containers/posix/libc/include/arch-arm/uart.h | 7 + containers/posix/libc/include/printf.h | 9 + containers/posix/libc/include/stdbool.h | 98 ++++ containers/posix/libc/include/stdint.h | 276 +++++++++ containers/posix/libc/include/stdio.h | 215 +++++++ containers/posix/libc/include/string.h | 11 + containers/posix/libc/src/arch | 1 + containers/posix/libc/src/arch-arm/eabi.c | 12 + containers/posix/libc/src/arch-arm/uart.c | 191 ++++++ containers/posix/libc/src/format.c | 543 ++++++++++++++++++ containers/posix/libc/src/format.h | 86 +++ containers/posix/libc/src/printf.c | 446 ++++++++++++++ containers/posix/libc/src/putc.c | 8 + containers/posix/libc/src/sprintf.c | 107 ++++ containers/posix/libc/src/string.c | 84 +++ .../libl4/include/l4lib/arch-arm/syslib.h | 2 +- containers/posix/mm0/SConscript | 2 +- containers/posix/mm0/container.c | 4 + containers/posix/mm0/include/file.h | 4 + containers/posix/mm0/include/linker.lds | 2 +- containers/posix/mm0/main.c | 4 +- containers/posix/mm0/src/arch-arm/crt0.S | 12 + containers/posix/mm0/src/arch-arm/mm.c | 1 + containers/posix/mm0/src/arch/crt0.S | 12 + containers/posix/mm0/src/bootm.c | 2 +- containers/posix/mm0/src/capability.c | 1 + containers/posix/mm0/src/file.c | 4 +- containers/posix/mm0/src/lib/addr.c | 2 +- containers/posix/mm0/src/lib/bit.c | 2 +- containers/posix/mm0/src/lib/elf/elf.c | 2 +- containers/posix/mm0/src/lib/idpool.c | 2 +- containers/posix/mm0/src/lib/malloc.c | 1 + containers/posix/mm0/src/mmap.c | 4 +- containers/posix/mm0/src/pagers.c | 12 +- containers/posix/mm0/src/test.c | 1 + containers/posix/mm0/src/utcb.c | 3 +- containers/posix/mm0/src/vm_object.c | 1 + containers/posix/test0/SConscript | 6 +- containers/posix/test0/include/linker.lds | 2 +- containers/posix/test0/include/tests.h | 3 +- containers/posix/test0/src/clonetest.c | 1 + containers/posix/test0/src/crt0.S | 12 + containers/posix/test0/src/dirtest.c | 3 +- containers/posix/test0/src/exectest.c | 1 + containers/posix/test0/src/fileio.c | 1 + containers/posix/test0/src/forktest.c | 1 + containers/posix/test0/src/mmaptest.c | 1 + containers/posix/test0/src/shmtest.c | 6 +- containers/posix/test0/src/test_exec/crt0.S | 12 + .../posix/test0/src/test_exec/test_exec.c | 2 +- 67 files changed, 2760 insertions(+), 53 deletions(-) create mode 100644 containers/posix/fs0/src/crt0.S create mode 100644 containers/posix/libc/SConscript rename containers/posix/{mm0/src => libc/include}/arch (100%) create mode 100644 containers/posix/libc/include/arch-arm/pl011_uart.h create mode 100644 containers/posix/libc/include/arch-arm/stdint.h create mode 100644 containers/posix/libc/include/arch-arm/uart.h create mode 100644 containers/posix/libc/include/printf.h create mode 100644 containers/posix/libc/include/stdbool.h create mode 100644 containers/posix/libc/include/stdint.h create mode 100644 containers/posix/libc/include/stdio.h create mode 100644 containers/posix/libc/include/string.h create mode 120000 containers/posix/libc/src/arch create mode 100644 containers/posix/libc/src/arch-arm/eabi.c create mode 100644 containers/posix/libc/src/arch-arm/uart.c create mode 100644 containers/posix/libc/src/format.c create mode 100644 containers/posix/libc/src/format.h create mode 100644 containers/posix/libc/src/printf.c create mode 100644 containers/posix/libc/src/putc.c create mode 100644 containers/posix/libc/src/sprintf.c create mode 100644 containers/posix/libc/src/string.c create mode 100644 containers/posix/mm0/src/arch-arm/crt0.S create mode 100644 containers/posix/mm0/src/arch/crt0.S create mode 100644 containers/posix/test0/src/crt0.S create mode 100644 containers/posix/test0/src/test_exec/crt0.S diff --git a/SConstruct b/SConstruct index 8d97130..f6ecbf3 100644 --- a/SConstruct +++ b/SConstruct @@ -138,14 +138,12 @@ else : libs = {} crts = {} - for variant in ['baremetal', 'userspace']: + for variant in ['baremetal']: (libs[variant], crts[variant]) = SConscript('libs/c/SConscript', variant_dir = buildDirectory + '/lib/c/' + variant, duplicate = 0, exports = {'environment': libraryEnvironment, 'variant': variant}) Depends((libs[variant], crts[variant]), libraryEnvironment['configFiles']) baseEnvironment['baremetal_libc'] = libs['baremetal'] baseEnvironment['baremetal_crt0'] = crts['baremetal'] - baseEnvironment['userspace_libc'] = libs['userspace'] - baseEnvironment['userspace_crt0'] = crts['userspace'] libelf = SConscript('libs/elf/SConscript', variant_dir = buildDirectory + '/lib/elf', duplicate = 0, exports = {'environment': libraryEnvironment}) Depends(libelf, libraryEnvironment['configFiles']) @@ -204,13 +202,13 @@ else : def buildTask(programName, sources, environment, previousImage, extraCppPath=None): e = environment.Clone() e.Append(LINKFLAGS=['-T' + posixServicesDirectory + programName + '/include/linker.lds']) - e.Append(LIBPATH=['#build/' + posixServicesDirectory + programName, '#build/lib/c/userspace/crt/sys-userspace/arch-arm']) + e.Append(LIBPATH=['#build/' + posixServicesDirectory + programName]) if extraCppPath: e.Append(CPPPATH=extraCppPath) objects = e.StaticObject(sources) Depends(objects, e['configFiles']) - program = e.Program(programName, objects + ['#' + e['userspace_crt0'][0].name]) + program = e.Program(programName, objects) environment['physicalBaseLinkerScript'] = Command('include/physical_base.lds', previousImage, 'tools/pyelf/readelf.py --first-free-page ' + previousImage[0].path + ' >> $TARGET') - Depends(program, [environment['physicalBaseLinkerScript'], e['userspace_crt0']]) + Depends(program, [environment['physicalBaseLinkerScript']]) return program tasksEnvironment = baseEnvironment.Clone( @@ -218,20 +216,18 @@ else : CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'], LINKFLAGS = ['-nostdlib'], ASFLAGS = ['-D__ASSEMBLY__'], - LIBS = [libs['userspace']] + taskLibraries + ['gcc', libs['userspace']], #### TODO: Why have the userspace C library twice? + LIBS = taskLibraries + ['gcc'] + taskLibraries, PROGSUFFIX = '.axf', CPPDEFINES = ['__USERSPACE__'], CPPPATH = ['#' + buildDirectory, '#' + buildDirectory + '/l4', '#' + includeDirectory, 'include', \ - '#' + posixServicesDirectory + 'libl4/include', '#' + posixServicesDirectory + 'libmem', '#' + posixServicesDirectory + 'libposix/include'], + '#' + posixServicesDirectory + 'libl4/include', '#' + posixServicesDirectory + 'libc/include', \ + '#' + posixServicesDirectory + 'libmem', '#' + posixServicesDirectory + 'libposix/include'], buildTask = buildTask) #### #### TODO: Why does the linker require crt0.o to be in the current directory and named as such. Is it #### because of the text in the linker script? #### - - userspaceRuntime = Command(crts['userspace'][0].name, crts['userspace'][0], 'ln -s $SOURCE.path $TARGET') - execfile(posixServicesDirectory + 'taskOrder.py') imageOrderData = [(taskName, []) for taskName in taskOrder] imageOrderData[0][1].append(startAxf) @@ -240,7 +236,6 @@ else : taskName = imageOrderData[i][0] dependency = imageOrderData[i][1] program = SConscript(posixServicesDirectory + taskName + '/SConscript', variant_dir = buildDirectory + '/' + posixServicesDirectory + taskName, duplicate = 0, exports = {'environment': tasksEnvironment, 'previousImage': dependency[0], 'posixServicesDirectory':posixServicesDirectory}) - Depends(program, userspaceRuntime) tasks.append(program) if i < len(imageOrderData) - 1: imageOrderData[i+1][1].append(program) diff --git a/containers/posix/fs0/SConscript b/containers/posix/fs0/SConscript index 10c9c26..23d88d3 100644 --- a/containers/posix/fs0/SConscript +++ b/containers/posix/fs0/SConscript @@ -19,6 +19,6 @@ Import('environment', 'previousImage') -program = environment['buildTask']('fs0', Glob('*.c') + [Glob(directory + '/*.c') for directory in [ 'src', 'src/lib', 'src/lib/elf', 'src/memfs']], environment, previousImage) +program = environment['buildTask']('fs0', Glob('*.c') + [Glob(directory + '/*.[cS]') for directory in [ 'src', 'src/lib', 'src/lib/elf', 'src/memfs']], environment, previousImage) Return('program') diff --git a/containers/posix/fs0/include/lib/malloc.h b/containers/posix/fs0/include/lib/malloc.h index 37479ff..ac514f2 100644 --- a/containers/posix/fs0/include/lib/malloc.h +++ b/containers/posix/fs0/include/lib/malloc.h @@ -3,6 +3,12 @@ #include #include +#ifndef NULL +#define NULL 0 +#endif +#ifndef size_t +#define size_t int +#endif void *kmalloc(size_t size); void kfree(void *blk); diff --git a/containers/posix/fs0/include/linker.lds b/containers/posix/fs0/include/linker.lds index d555415..fed94eb 100644 --- a/containers/posix/fs0/include/linker.lds +++ b/containers/posix/fs0/include/linker.lds @@ -26,7 +26,7 @@ SECTIONS { . = virtual_base; _start_text = .; - .text : AT (ADDR(.text) - offset) { crt0.o(.text) *(.text) } + .text : AT (ADDR(.text) - offset) { *(.text.head) *(.text) } /* rodata is needed else your strings will link at physical! */ .rodata : AT (ADDR(.rodata) - offset) { *(.rodata) } .rodata1 : AT (ADDR(.rodata1) - offset) { *(.rodata1) } diff --git a/containers/posix/fs0/include/vfs.h b/containers/posix/fs0/include/vfs.h index 5d9b5a8..4f94898 100644 --- a/containers/posix/fs0/include/vfs.h +++ b/containers/posix/fs0/include/vfs.h @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include diff --git a/containers/posix/fs0/main.c b/containers/posix/fs0/main.c index 7fc7475..b5b672b 100644 --- a/containers/posix/fs0/main.c +++ b/containers/posix/fs0/main.c @@ -122,7 +122,7 @@ void handle_fs_requests(void) default: printf("%s: Unrecognised ipc tag (%d) " "received from tid: %d. Ignoring.\n", __TASKNAME__, - mr[MR_TAG], sender); + mr[MR_TAG], senderid); } /* Reply */ diff --git a/containers/posix/fs0/src/crt0.S b/containers/posix/fs0/src/crt0.S new file mode 100644 index 0000000..a390ee9 --- /dev/null +++ b/containers/posix/fs0/src/crt0.S @@ -0,0 +1,12 @@ + +.section .text.head +.global _start; +.type _start,function; +.align; + +_start: + ldr sp, =__stack + bl __container_init +1: + b 1b + diff --git a/containers/posix/fs0/src/file.c b/containers/posix/fs0/src/file.c index 2bfd6fe..4b4963e 100644 --- a/containers/posix/fs0/src/file.c +++ b/containers/posix/fs0/src/file.c @@ -8,7 +8,7 @@ #include #include #include INC_GLUE(memory.h) -#include +#include /* * This reads contents of a file in pages, calling the fs-specific file read function to read-in diff --git a/containers/posix/fs0/src/lib/bit.c b/containers/posix/fs0/src/lib/bit.c index 7b1dee4..d4e1226 100644 --- a/containers/posix/fs0/src/lib/bit.c +++ b/containers/posix/fs0/src/lib/bit.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include INC_GLUE(memory.h) /* Emulation of ARM's CLZ (count leading zeroes) instruction */ diff --git a/containers/posix/fs0/src/lib/idpool.c b/containers/posix/fs0/src/lib/idpool.c index 0cb826e..13ca67b 100644 --- a/containers/posix/fs0/src/lib/idpool.c +++ b/containers/posix/fs0/src/lib/idpool.c @@ -8,7 +8,7 @@ #include // --> This is a local library that statically allocates its heap. #include #include INC_GLUE(memory.h) -#include +#include #include struct id_pool *id_pool_new_init(int totalbits) diff --git a/containers/posix/fs0/src/lib/malloc.c b/containers/posix/fs0/src/lib/malloc.c index 27c3829..5b6a344 100644 --- a/containers/posix/fs0/src/lib/malloc.c +++ b/containers/posix/fs0/src/lib/malloc.c @@ -18,7 +18,8 @@ Messages that indicate a software error will contain three asterisks (***). *****************************************************************************/ #include /* memcpy(), memset() */ #include /* printf() */ - +#include +#include #define _32BIT 1 /* use small (32K) heap for 16-bit compilers, diff --git a/containers/posix/fs0/src/lib/vaddr.c b/containers/posix/fs0/src/lib/vaddr.c index 8a847a7..f199cfc 100644 --- a/containers/posix/fs0/src/lib/vaddr.c +++ b/containers/posix/fs0/src/lib/vaddr.c @@ -8,7 +8,7 @@ #include #include INC_GLUE(memory.h) #include -#include +#include void vaddr_pool_init(struct id_pool *pool, unsigned long start, unsigned long end) { diff --git a/containers/posix/fs0/src/memfs/memfs.c b/containers/posix/fs0/src/memfs/memfs.c index 95d957f..72bb764 100644 --- a/containers/posix/fs0/src/memfs/memfs.c +++ b/containers/posix/fs0/src/memfs/memfs.c @@ -192,7 +192,7 @@ struct superblock *memfs_get_superblock(void *block) return 0; } if (sb->magic != MEMFS_MAGIC) { - printf("%s: Magic number not match: %s\n", __FUNCTION__, sb->magic); + printf("%s: Magic number not match: %u\n", __FUNCTION__, sb->magic); return 0; } diff --git a/containers/posix/libc/SConscript b/containers/posix/libc/SConscript new file mode 100644 index 0000000..dd33c24 --- /dev/null +++ b/containers/posix/libc/SConscript @@ -0,0 +1,31 @@ +# -*- mode: python; coding: utf-8; -*- + +# Codezero -- a microkernel for embedded systems. +# +# Copyright © 2009 B Labs Ltd +# +# 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 3 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, see +# . +# +# Author: Russel Winder + +Import('environment', 'posixServicesDirectory') + +e = environment.Clone() +e.Append(CPPPATH = ['include', 'include/arch']) + +e['CCFLAGS'] = ['-g', '-nostdlib', '-Wall', '-ffreestanding', '-std=gnu99'] + +objects = e.StaticObject(Glob('src/*.c') + Glob('src/arch-' + environment['ARCH'] + '/*.[cS]')) +Depends(objects, e['configFiles']) +library = e.StaticLibrary('c', objects) + +Return('library') diff --git a/containers/posix/mm0/src/arch b/containers/posix/libc/include/arch similarity index 100% rename from containers/posix/mm0/src/arch rename to containers/posix/libc/include/arch diff --git a/containers/posix/libc/include/arch-arm/pl011_uart.h b/containers/posix/libc/include/arch-arm/pl011_uart.h new file mode 100644 index 0000000..7de009d --- /dev/null +++ b/containers/posix/libc/include/arch-arm/pl011_uart.h @@ -0,0 +1,407 @@ + +#ifndef __PL011__UART__H__ +#define __PL011__UART__H__ + +/* + * PL011 UART Generic driver implementation. + * Copyright Bahadir Balban (C) 2006 + * + * The particular intention of this code is that it has been carefully + * written as decoupled from os-specific code and in a verbose way such + * that it clearly demonstrates how the device operates, reducing the + * amount of time to be spent for understanding the operational model + * and implementing a driver from scratch. This is the very first to be + * such a driver so far, hopefully it will turn out to be useful. + */ + +/* Default base address for this chip */ +#define PL011_USR_BASE 0x500000 +#define PL011_BASE PL011_USR_BASE + +/* Architecture specific memory access macros */ +#define read(val, address) val = *((volatile unsigned int *) address) +#define write(val, address) *((volatile unsigned int *) address) = val + +/* Register offsets */ +#define PL011_UARTDR (PL011_BASE + 0x00) +#define PL011_UARTRSR (PL011_BASE + 0x04) +#define PL011_UARTECR (PL011_BASE + 0x04) +#define PL011_UARTFR (PL011_BASE + 0x18) +#define PL011_UARTILPR (PL011_BASE + 0x20) +#define PL011_UARTIBRD (PL011_BASE + 0x24) +#define PL011_UARTFBRD (PL011_BASE + 0x28) +#define PL011_UARTLCR_H (PL011_BASE + 0x2C) +#define PL011_UARTCR (PL011_BASE + 0x30) +#define PL011_UARTIFLS (PL011_BASE + 0x34) +#define PL011_UARTIMSC (PL011_BASE + 0x38) +#define PL011_UARTRIS (PL011_BASE + 0x3C) +#define PL011_UARTMIS (PL011_BASE + 0x40) +#define PL011_UARTICR (PL011_BASE + 0x44) +#define PL011_UARTDMACR (PL011_BASE + 0x48) + +/* IRQ bits for each uart irq event */ +#define PL011_RXIRQ (1 << 4) +#define PL011_TXIRQ (1 << 5) +#define PL011_RXTIMEOUTIRQ (1 << 6) +#define PL011_FEIRQ (1 << 7) +#define PL011_PEIRQ (1 << 8) +#define PL011_BEIRQ (1 << 9) +#define PL011_OEIRQ (1 << 10) + +struct pl011_uart; + +int pl011_initialise(struct pl011_uart *); +int pl011_tx_char(char); +int pl011_rx_char(char *); + +void pl011_set_baudrate(unsigned int, unsigned int); +void pl011_set_irq_mask(unsigned int); +void pl011_clr_irq_mask(unsigned int); + +void pl011_irq_handler(struct pl011_uart *); +void pl011_tx_irq_handler(struct pl011_uart *, unsigned int); +void pl011_rx_irq_handler(struct pl011_uart *, unsigned int); +void pl011_error_irq_handler(struct pl011_uart *, unsigned int); + +static inline void pl011_uart_enable(void); +static inline void pl011_uart_disable(void); +static inline void pl011_tx_enable(void); +static inline void pl011_tx_disable(void); +static inline void pl011_rx_enable(void); +static inline void pl011_rx_disable(void); +static inline void pl011_irq_clear(unsigned int flags); +static inline unsigned int pl011_read_irqstat(void); +static inline unsigned int pl011_read_irqmask(void); +static inline void pl011_rx_dma_disable(void); +static inline void pl011_rx_dma_enable(void); +static inline void pl011_tx_dma_enable(void); +static inline void pl011_tx_dma_disable(void); +static inline void pl011_set_irq_fifolevel(unsigned int xfer, + unsigned int level); +static inline void pl011_set_word_width(int size); +static inline void pl011_disable_fifos(void); +static inline void pl011_set_parity_even(void); +static inline void pl011_parity_enable(void); +static inline void pl011_set_stopbits(int stopbits); + +static inline void pl011_set_parity_odd(void); +static inline void pl011_enable_fifos(void); +static inline void pl011_parity_disable(void); + +struct pl011_uart_ops { + int (*initialise)(struct pl011_uart *); + + int (*tx_char)(char); + int (*rx_char)(char *); + + void (*set_baudrate)(unsigned int, unsigned int); + void (*set_irq_mask)(unsigned int); + void (*clr_irq_mask)(unsigned int); + + void (*irq_handler)(struct pl011_uart *); + void (*tx_irq_handler)(struct pl011_uart *, unsigned int); + void (*rx_irq_handler)(struct pl011_uart *, unsigned int); + void (*error_irq_handler)(struct pl011_uart *, unsigned int); +}; + +struct pl011_uart { + unsigned int base; + struct pl011_uart_ops ops; + unsigned int frame_errors; + unsigned int parity_errors; + unsigned int break_errors; + unsigned int overrun_errors; + unsigned int rx_timeout_errors; +}; + + + +#define PL011_UARTEN (1 << 0) +static inline void pl011_uart_enable() +{ + unsigned int val; + val = 0; + + read(val, PL011_UARTCR); + val |= PL011_UARTEN; + write(val, PL011_UARTCR); + + return; +} + +static inline void pl011_uart_disable() +{ + unsigned int val; + val = 0; + + read(val, PL011_UARTCR); + val &= ~PL011_UARTEN; + write(val, PL011_UARTCR); + + return; +} + +#define PL011_TXE (1 << 8) +static inline void pl011_tx_enable() +{ + unsigned int val; + val = 0; + + read(val, PL011_UARTCR); + val |= PL011_TXE; + write(val, PL011_UARTCR); + return; +} + +static inline void pl011_tx_disable() +{ + unsigned int val; + val = 0; + + read(val, PL011_UARTCR); + val &= ~PL011_TXE; + write(val, PL011_UARTCR); + return; +} + + +#define PL011_RXE (1 << 9) +static inline void pl011_rx_enable() +{ + unsigned int val; + val = 0; + + read(val, PL011_UARTCR); + val |= PL011_RXE; + write(val, PL011_UARTCR); + return; +} + +static inline void pl011_rx_disable() +{ + unsigned int val; + val = 0; + + read(val, PL011_UARTCR); + val &= ~PL011_RXE; + write(val, PL011_UARTCR); + return; +} + +#define PL011_TWO_STOPBITS_SELECT (1 << 3) +static inline void pl011_set_stopbits(int stopbits) +{ + unsigned int val; + val = 0; + + read(val, PL011_UARTLCR_H); + + if(stopbits == 2) { /* Set to two bits */ + val |= PL011_TWO_STOPBITS_SELECT; + } else { /* Default is 1 */ + val &= ~PL011_TWO_STOPBITS_SELECT; + } + write(val, PL011_UARTLCR_H); + return; +} + +#define PL011_PARITY_ENABLE (1 << 1) +static inline void pl011_parity_enable() +{ + unsigned int val; + val = 0; + + read(val, PL011_UARTLCR_H); + val |= PL011_PARITY_ENABLE; + write(val, PL011_UARTLCR_H); + return; +} + +static inline void pl011_parity_disable() +{ + unsigned int val; + val = 0; + + read(val, PL011_UARTLCR_H); + val &= ~PL011_PARITY_ENABLE; + write(val, PL011_UARTLCR_H); + return; +} + +#define PL011_PARITY_EVEN (1 << 2) +static inline void pl011_set_parity_even() +{ + unsigned int val; + val = 0; + + read(val, PL011_UARTLCR_H); + val |= PL011_PARITY_EVEN; + write(val, PL011_UARTLCR_H); + return; +} + +static inline void pl011_set_parity_odd() +{ + unsigned int val; + val = 0; + + read(val, PL011_UARTLCR_H); + val &= ~PL011_PARITY_EVEN; + write(val, PL011_UARTLCR_H); + return; +} + +#define PL011_ENABLE_FIFOS (1 << 4) +static inline void pl011_enable_fifos() +{ + unsigned int val; + val = 0; + + read(val, PL011_UARTLCR_H); + val |= PL011_ENABLE_FIFOS; + write(val, PL011_UARTLCR_H); + return; +} + +static inline void pl011_disable_fifos() +{ + unsigned int val; + val = 0; + + read(val, PL011_UARTLCR_H); + val &= ~PL011_ENABLE_FIFOS; + write(val, PL011_UARTLCR_H); + return; +} + + +#define PL011_WORD_WIDTH_SHIFT (5) +/* Sets the transfer word width for the data register. */ +static inline void pl011_set_word_width(int size) +{ + unsigned int val; + val = 0; + + if(size < 5 || size > 8) /* Default is 8 */ + size = 8; + + /* Clear size field */ + read(val, PL011_UARTLCR_H); + val &= ~(0x3 << PL011_WORD_WIDTH_SHIFT); + write(val, PL011_UARTLCR_H); + + /* The formula is to write 5 less of size given: + * 11 = 8 bits + * 10 = 7 bits + * 01 = 6 bits + * 00 = 5 bits + */ + read(val, PL011_UARTLCR_H); + val |= (size - 5) << PL011_WORD_WIDTH_SHIFT; + write(val, PL011_UARTLCR_H); + + return; +} + +/* + * Defines at which level of fifo fullness an irq will be generated. + * @xfer: tx fifo = 0, rx fifo = 1 + * @level: Generate irq if: + * 0 rxfifo >= 1/8 full txfifo <= 1/8 full + * 1 rxfifo >= 1/4 full txfifo <= 1/4 full + * 2 rxfifo >= 1/2 full txfifo <= 1/2 full + * 3 rxfifo >= 3/4 full txfifo <= 3/4 full + * 4 rxfifo >= 7/8 full txfifo <= 7/8 full + * 5-7 reserved reserved + */ +static inline void pl011_set_irq_fifolevel(unsigned int xfer, unsigned int level) +{ + if(xfer != 1 && xfer != 0) /* Invalid fifo */ + return; + + if(level > 4) /* Invalid level */ + return; + + write(level << (xfer * 3), PL011_UARTIFLS); + return; +} + +/* returns which irqs are masked */ +static inline unsigned int pl011_read_irqmask(void) +{ + unsigned int flags; + read(flags, PL011_UARTIMSC); + return flags; +} + +/* returns masked irq status */ +static inline unsigned int pl011_read_irqstat(void) +{ + unsigned int irqstatus; + read(irqstatus, PL011_UARTMIS); + return irqstatus; +} +/* Clears the given asserted irqs */ +static inline void pl011_irq_clear(unsigned int flags) +{ + if(flags > 0x3FF) { /* Invalid irq clearing bitvector */ + return; + } + /* Simply write the flags since it's a write-only register */ + write(flags, PL011_UARTICR); + return; +} + +#define PL011_TXDMAEN (1 << 1) +#define PL011_RXDMAEN (1 << 0) + +/* Enables dma transfers for uart. The dma controller + * must be initialised, set-up and enabled separately. + */ +static inline void pl011_tx_dma_enable() +{ + unsigned int val; + val = 0; + + read(val, PL011_UARTDMACR); + val |= PL011_TXDMAEN; + write(val, PL011_UARTDMACR); + return; +} + +/* Disables dma transfers for uart */ +static inline void pl011_tx_dma_disable() +{ + unsigned int val; + val = 0; + + read(val, PL011_UARTDMACR); + val &= ~PL011_TXDMAEN; + write(val, PL011_UARTDMACR); + return; +} + +static inline void pl011_rx_dma_enable() +{ + unsigned int val; + val = 0; + + read(val, PL011_UARTDMACR); + val |= PL011_RXDMAEN; + write(val, PL011_UARTDMACR); + return; +} + +static inline void pl011_rx_dma_disable() +{ + unsigned int val; + val = 0; + + read(val, PL011_UARTDMACR); + val &= ~PL011_RXDMAEN; + write(val, PL011_UARTDMACR); + return; +} + +#endif /* __PL011__UART__ */ + diff --git a/containers/posix/libc/include/arch-arm/stdint.h b/containers/posix/libc/include/arch-arm/stdint.h new file mode 100644 index 0000000..6078b0a --- /dev/null +++ b/containers/posix/libc/include/arch-arm/stdint.h @@ -0,0 +1,92 @@ +/* + * Australian Public Licence B (OZPLB) + * + * Version 1-0 + * + * Copyright (c) 2004 National ICT Australia + * + * All rights reserved. + * + * Developed by: Embedded, Real-time and Operating Systems Program (ERTOS) + * National ICT Australia + * http://www.ertos.nicta.com.au + * + * Permission is granted by National ICT Australia, free of charge, to + * any person obtaining a copy of this software and any associated + * documentation files (the "Software") to deal with the Software without + * restriction, including (without limitation) the rights to use, copy, + * modify, adapt, merge, publish, distribute, communicate to the public, + * sublicense, and/or sell, lend or rent out copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimers. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimers in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of National ICT Australia, nor the names of its + * contributors, may be used to endorse or promote products derived + * from this Software without specific prior written permission. + * + * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT + * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND + * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS, + * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS + * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, + * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF + * ERRORS, WHETHER OR NOT DISCOVERABLE. + * + * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL + * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL + * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER + * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR + * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS + * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR + * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT, + * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN + * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER + * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS + * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS, + * DAMAGES OR OTHER LIABILITY. + * + * If applicable legislation implies representations, warranties, or + * conditions, or imposes obligations or liability on National ICT + * Australia or one of its contributors in respect of the Software that + * cannot be wholly or partly excluded, restricted or modified, the + * liability of National ICT Australia or the contributor is limited, to + * the full extent permitted by the applicable legislation, at its + * option, to: + * a. in the case of goods, any one or more of the following: + * i. the replacement of the goods or the supply of equivalent goods; + * ii. the repair of the goods; + * iii. the payment of the cost of replacing the goods or of acquiring + * equivalent goods; + * iv. the payment of the cost of having the goods repaired; or + * b. in the case of services: + * i. the supplying of the services again; or + * ii. the payment of the cost of having the services supplied again. + * + * The construction, validity and performance of this licence is governed + * by the laws in force in New South Wales, Australia. + */ +/* + Author: Ben Leslie +*/ +typedef signed char int8_t; +typedef short int16_t; +typedef int int32_t; +typedef long long int64_t; + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; + +#define __PTR_SIZE 32 diff --git a/containers/posix/libc/include/arch-arm/uart.h b/containers/posix/libc/include/arch-arm/uart.h new file mode 100644 index 0000000..2ea71dc --- /dev/null +++ b/containers/posix/libc/include/arch-arm/uart.h @@ -0,0 +1,7 @@ +#ifndef __LIBC_UART_H__ +#define __LIBC_UART_H__ + +void uart_init(void); +void uart_putc(char c); + +#endif /* __LIBC_UART_H__ */ diff --git a/containers/posix/libc/include/printf.h b/containers/posix/libc/include/printf.h new file mode 100644 index 0000000..446157b --- /dev/null +++ b/containers/posix/libc/include/printf.h @@ -0,0 +1,9 @@ + +#ifndef __PRINTF_H__ +#define __PRINTF_H__ + +#include +#include +int printf(char *format, ...) __attribute__((format (printf, 1, 2))); + +#endif /* __PRINTF_H__ */ diff --git a/containers/posix/libc/include/stdbool.h b/containers/posix/libc/include/stdbool.h new file mode 100644 index 0000000..34e0ac7 --- /dev/null +++ b/containers/posix/libc/include/stdbool.h @@ -0,0 +1,98 @@ +/* + * Australian Public Licence B (OZPLB) + * + * Version 1-0 + * + * Copyright (c) 2004 National ICT Australia + * + * All rights reserved. + * + * Developed by: Embedded, Real-time and Operating Systems Program (ERTOS) + * National ICT Australia + * http://www.ertos.nicta.com.au + * + * Permission is granted by National ICT Australia, free of charge, to + * any person obtaining a copy of this software and any associated + * documentation files (the "Software") to deal with the Software without + * restriction, including (without limitation) the rights to use, copy, + * modify, adapt, merge, publish, distribute, communicate to the public, + * sublicense, and/or sell, lend or rent out copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimers. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimers in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of National ICT Australia, nor the names of its + * contributors, may be used to endorse or promote products derived + * from this Software without specific prior written permission. + * + * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT + * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND + * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS, + * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS + * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, + * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF + * ERRORS, WHETHER OR NOT DISCOVERABLE. + * + * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL + * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL + * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER + * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR + * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS + * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR + * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT, + * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN + * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER + * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS + * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS, + * DAMAGES OR OTHER LIABILITY. + * + * If applicable legislation implies representations, warranties, or + * conditions, or imposes obligations or liability on National ICT + * Australia or one of its contributors in respect of the Software that + * cannot be wholly or partly excluded, restricted or modified, the + * liability of National ICT Australia or the contributor is limited, to + * the full extent permitted by the applicable legislation, at its + * option, to: + * a. in the case of goods, any one or more of the following: + * i. the replacement of the goods or the supply of equivalent goods; + * ii. the repair of the goods; + * iii. the payment of the cost of replacing the goods or of acquiring + * equivalent goods; + * iv. the payment of the cost of having the goods repaired; or + * b. in the case of services: + * i. the supplying of the services again; or + * ii. the payment of the cost of having the services supplied again. + * + * The construction, validity and performance of this licence is governed + * by the laws in force in New South Wales, Australia. + */ + +/* + Author: Ben Leslie + Description: + Implementation based on C99 Section 7.16 Boolean type and values +*/ + +#ifndef __STDBOOL_H__ +#define __STDBOOL_H__ + +#ifndef __bool_true_false_are_defined + +#define __bool_true_false_are_defined 1 +#define bool _Bool +#define true 1 +#define false 0 + +#endif /* __bool_true_false_are_defined */ + +#endif /* __STDBOOL_H__ */ diff --git a/containers/posix/libc/include/stdint.h b/containers/posix/libc/include/stdint.h new file mode 100644 index 0000000..add4c6d --- /dev/null +++ b/containers/posix/libc/include/stdint.h @@ -0,0 +1,276 @@ +/* + * Australian Public Licence B (OZPLB) + * + * Version 1-0 + * + * Copyright (c) 2004 National ICT Australia + * + * All rights reserved. + * + * Developed by: Embedded, Real-time and Operating Systems Program (ERTOS) + * National ICT Australia + * http://www.ertos.nicta.com.au + * + * Permission is granted by National ICT Australia, free of charge, to + * any person obtaining a copy of this software and any associated + * documentation files (the "Software") to deal with the Software without + * restriction, including (without limitation) the rights to use, copy, + * modify, adapt, merge, publish, distribute, communicate to the public, + * sublicense, and/or sell, lend or rent out copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimers. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimers in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of National ICT Australia, nor the names of its + * contributors, may be used to endorse or promote products derived + * from this Software without specific prior written permission. + * + * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT + * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND + * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS, + * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS + * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, + * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF + * ERRORS, WHETHER OR NOT DISCOVERABLE. + * + * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL + * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL + * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER + * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR + * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS + * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR + * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT, + * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN + * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER + * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS + * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS, + * DAMAGES OR OTHER LIABILITY. + * + * If applicable legislation implies representations, warranties, or + * conditions, or imposes obligations or liability on National ICT + * Australia or one of its contributors in respect of the Software that + * cannot be wholly or partly excluded, restricted or modified, the + * liability of National ICT Australia or the contributor is limited, to + * the full extent permitted by the applicable legislation, at its + * option, to: + * a. in the case of goods, any one or more of the following: + * i. the replacement of the goods or the supply of equivalent goods; + * ii. the repair of the goods; + * iii. the payment of the cost of replacing the goods or of acquiring + * equivalent goods; + * iv. the payment of the cost of having the goods repaired; or + * b. in the case of services: + * i. the supplying of the services again; or + * ii. the payment of the cost of having the services supplied again. + * + * The construction, validity and performance of this licence is governed + * by the laws in force in New South Wales, Australia. + */ +#ifndef _STDINT_H_ +#define _STDINT_H_ + +#include + +/* + * 7.18.1.1 Exact-width integers + */ +#include + +/* + * 7.18.2.1 Limits of exact-wdith integer types + */ +#define INT8_MIN SCHAR_MIN +#define INT16_MIN SHRT_MIN +#define INT32_MIN INT_MIN +#define INT64_MIN LLONG_MIN + +#define INT8_MAX SCHAR_MAX +#define INT16_MAX SHRT_MAX +#define INT32_MAX INT_MAX +#define INT64_MAX LLONG_MAX + +#define UINT8_MAX UCHAR_MAX +#define UINT16_MAX USHRT_MAX +#define UINT32_MAX UINT_MAX +#define UINT64_MAX ULLONG_MAX + + +#ifndef __ARCH_HAS_LEAST +/* + * 7.18.1.2 Minimum-width integers + */ +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; + +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +/* + * 7.18.2.2 Limits of minimum-width integers + */ +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST64_MIN INT64_MIN + +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MAX INT64_MAX + +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX +#else +#undef __ARCH_HAS_LEAST +#endif + + +#ifndef __ARCH_HAS_FAST +/* + * 7.8.1.3 Fastest minimum-width integer types + * Note -- We fulfil the spec, however we don't really know + * which are fastest here. I assume `int' is probably fastest + * more most, and should be used for [u]int_fast[8,16,32]_t. + */ + +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; + +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +/* + * 7.18.2.2 Limits of fastest minimum-width integers + */ +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST64_MIN INT64_MIN + +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MAX INT64_MAX + +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX +#else +#undef __ARCH_HAS_FAST +#endif + +/* + * 7.18.1.4 Integer types capable of holding object pointers + * We should fix this to be 32/64 clean. + */ +#if __PTR_SIZE==32 +typedef int32_t intptr_t; +typedef uint32_t uintptr_t; + +#define INTPTR_MIN INT32_MIN +#define INTPTR_MAX INT32_MAX +#define UINTPTR_MAX UINT32_MAX + +#elif __PTR_SIZE==64 +typedef int64_t intptr_t; +typedef uint64_t uintptr_t; + +#define INTPTR_MIN INT64_MIN +#define INTPTR_MAX INT64_MAX +#define UINTPTR_MAX UINT64_MAX +#else +#error Unknown pointer size +#endif + +#undef __PTR_SIZE + +/* + * 7.18.1.5 Greatest-wdith integer types + */ +typedef long long int intmax_t; +typedef unsigned long long int uintmax_t; + +/* + * 7.18.2.5 Limits of greateast-width integer types + */ +#define INTMAX_MIN LLONG_MIN +#define INTMAX_MAX LLONG_MAX +#define UINTMAX_MAX ULLONG_MAX + +/* + * 7.18.3 Limits of other integer types + */ +/* FIXME: Check these limits are correct */ +#define PTRDIFF_MIN INTPTR_MIN +#define PTRDIFF_MAX INTPTR_MAX + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#define SIZE_MAX UINTPTR_MAX + +#define WCHAR_MIN 0 +#define WCHAR_MAX UINT16_MAX + +#define WINT_MIN 0 +#define WINT_MAX UINT16_MAX + +/* + * 7.18.4 Macros for integer constants + */ + +#define INT8_C(x) (int8_t)(x) +#define INT16_C(x) (int16_t)(x) +#define INT32_C(x) (int32_t)(x) +#define INT64_C(x) (int64_t)(x) +#define UINT8_C(x) (uint8_t)(x) +#define UINT16_C(x) (uint16_t)(x) +#define UINT32_C(x) (uint32_t)(x) +#define UINT64_C(x) (uint64_t)(x) + +#define INT_FAST8_C(x) (int_fast8_t)(x) +#define INT_FAST16_C(x) (int_fast16_t)(x) +#define INT_FAST32_C(x) (int_fast32_t)(x) +#define INT_FAST64_C(x) (int_fast64_t)(x) +#define UINT_FAST8_C(x) (uint_fast8_t)(x) +#define UINT_FAST16_C(x) (uint_fast16_t)(x) +#define UINT_FAST32_C(x) (uint_fast32_t)(x) +#define UINT_FAST64_C(x) (uint_fast64_t)(x) + +#define INT_LEAST8_C(x) (int_least8_t)(x) +#define INT_LEAST16_C(x) (int_least16_t)(x) +#define INT_LEAST32_C(x) (int_least32_t)(x) +#define INT_LEAST64_C(x) (int_least64_t)(x) +#define UINT_LEAST8_C(x) (uint_least8_t)(x) +#define UINT_LEAST16_C(x) (uint_least16_t)(x) +#define UINT_LEAST32_C(x) (uint_least32_t)(x) +#define UINT_LEAST64_C(x) (uint_least64_t)(x) + +#define INTPTR_C(x) (intptr_t)(x) +#define UINTPTR_C(x) (uintptr_t)(x) + +#define INTMAX_C(x) (intmax_t)(x) +#define UINTMAX_C(x) (uintmax_t)(x) + +#endif /* _STDINT_H_ */ diff --git a/containers/posix/libc/include/stdio.h b/containers/posix/libc/include/stdio.h new file mode 100644 index 0000000..dfc2af0 --- /dev/null +++ b/containers/posix/libc/include/stdio.h @@ -0,0 +1,215 @@ +/* + * Australian Public Licence B (OZPLB) + * + * Version 1-0 + * + * Copyright (c) 2004 National ICT Australia + * + * All rights reserved. + * + * Developed by: Embedded, Real-time and Operating Systems Program (ERTOS) + * National ICT Australia + * http://www.ertos.nicta.com.au + * + * Permission is granted by National ICT Australia, free of charge, to + * any person obtaining a copy of this software and any associated + * documentation files (the "Software") to deal with the Software without + * restriction, including (without limitation) the rights to use, copy, + * modify, adapt, merge, publish, distribute, communicate to the public, + * sublicense, and/or sell, lend or rent out copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimers. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimers in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of National ICT Australia, nor the names of its + * contributors, may be used to endorse or promote products derived + * from this Software without specific prior written permission. + * + * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT + * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND + * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS, + * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS + * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, + * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF + * ERRORS, WHETHER OR NOT DISCOVERABLE. + * + * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL + * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL + * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER + * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR + * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS + * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR + * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT, + * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN + * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER + * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS + * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS, + * DAMAGES OR OTHER LIABILITY. + * + * If applicable legislation implies representations, warranties, or + * conditions, or imposes obligations or liability on National ICT + * Australia or one of its contributors in respect of the Software that + * cannot be wholly or partly excluded, restricted or modified, the + * liability of National ICT Australia or the contributor is limited, to + * the full extent permitted by the applicable legislation, at its + * option, to: + * a. in the case of goods, any one or more of the following: + * i. the replacement of the goods or the supply of equivalent goods; + * ii. the repair of the goods; + * iii. the payment of the cost of replacing the goods or of acquiring + * equivalent goods; + * iv. the payment of the cost of having the goods repaired; or + * b. in the case of services: + * i. the supplying of the services again; or + * ii. the payment of the cost of having the services supplied again. + * + * The construction, validity and performance of this licence is governed + * by the laws in force in New South Wales, Australia. + */ + +/* +Author: Ben Leslie +*/ + +#ifndef _STDIO_H_ +#define _STDIO_H_ + +#include +#include + +#ifdef THREAD_SAFE +#include +#define lock_stream(s) mutex_count_lock(&(s)->mutex) +#define unlock_stream(s) mutex_count_unlock(&(s)->mutex) +#else +#define lock_stream(s) +#define unlock_stream(s) +#endif + +#define __UNGET_SIZE 10 + +struct __file { + void *handle; + + size_t (*read_fn)(void *, long int, size_t, void *); + size_t (*write_fn)(void *, long int, size_t, void *); + int (*close_fn)(void *); + long int (*eof_fn)(void *); + + unsigned char buffering_mode; + char *buffer; + + unsigned char unget_pos; + long int current_pos; + +#ifdef THREAD_SAFE + struct mutex mutex; +#endif + + int eof; + int error; + + char unget_stack[__UNGET_SIZE]; +}; + +typedef struct __file FILE; /* This needs to be done correctly */ +typedef long fpos_t; /* same */ + +#define _IOFBF 0 +#define _IOLBF 1 +#define _IONBF 2 + +#define BUFSIZ 37 +#define EOF (-1) + +#define FOPEN_MAX 37 +#define FILENAME_MAX 37 +#define L_tmpnam 37 + +//#define SEEK_CUR 0 +//#define SEEK_END 1 +//#define SEEK_SET 2 + +#define TMP_MAX 37 + +extern FILE *stderr; +extern FILE *stdin; +extern FILE *stdout; + +/* 7.19.4 Operations on files */ +int remove(const char *); +int rename(const char *, const char *); +FILE *tmpfile(void); +char *tmpnam(char *); +int fclose(FILE *); +int fflush(FILE *); +FILE *fopen(const char *, const char *); +FILE *freopen(const char *, const char *, FILE *); +void setbuf(FILE *, char *); +int setvbuf(FILE *, char *, int, size_t); + +/* 7.19.6 Format i/o functions */ +int fprintf(FILE *, const char *, ...); +int fscanf(FILE *, const char *, ...); +//int printf(const char *format, ...) __attribute__((format (printf, 1, 2))); +int scanf(const char *, ...); +int snprintf(char *, size_t , const char *, ...); +int sprintf(char *, const char *, ...); +int sscanf(const char *, const char *, ...); +int vfprintf(FILE *, const char *, va_list); +int vfscanf(FILE *, const char *, va_list); +int vprintf(const char *, va_list); +int vscanf(const char *, va_list); +int vsnprintf(char *, size_t, const char *, va_list ); +int vsprintf(char *, const char *format, va_list arg); +int vsscanf(const char *s, const char *format, va_list arg); + +/* 7.19.7 Character i/o functions */ +int fgetc(FILE *); +char *fgets(char *, int, FILE *); +//int fputc(int, FILE *); +int fputs(const char *, FILE *); + +/* getc is specified to be the same as fgetc, so it makes + the most sense to implement as a macro here */ +#define getc fgetc /*int getc(FILE *); */ + +int getchar(void); +char *gets(char *); + +/* putc is specified to be the same as fputc, so it makes + the most sense to implement as a macro here */ +//#define putc fputc /*int fetc(int, FILE *); */ + +int putchar(int); +int puts(const char *); +int ungetc(int, FILE *); + +/* 7.19.8 Direct I/O functions */ +size_t fread(void *, size_t, size_t, FILE *); +size_t fwrite(const void *, size_t, size_t, FILE *); + +/* 7.19.9 File positioning functions */ +int fgetpos(FILE *, fpos_t *); +int fseek(FILE *, long int, int); +int fsetpos(FILE *, const fpos_t *); +long int ftell(FILE *); +void rewind(FILE *); + +/* 7.19.10 Error-handling functions */ +void clearerr(FILE *); +int feof(FILE *); +int ferror(FILE *); +void perror(const char *); + +#endif /* _STDIO_H_ */ diff --git a/containers/posix/libc/include/string.h b/containers/posix/libc/include/string.h new file mode 100644 index 0000000..1ca9ec5 --- /dev/null +++ b/containers/posix/libc/include/string.h @@ -0,0 +1,11 @@ +#ifndef __LIB_STRING_H__ +#define __LIB_STRING_H__ + +int strlen(const char *s); +char *strcpy(char *to, const char *from); +char *strncpy(char *dest, const char *src, int count); +int strcmp(const char *s1, const char *s2); +void *memset(void *p, int c, int size); +void *memcpy(void *d, void *s, int size); + +#endif /* __LIB_STRING_H__ */ diff --git a/containers/posix/libc/src/arch b/containers/posix/libc/src/arch new file mode 120000 index 0000000..85405c2 --- /dev/null +++ b/containers/posix/libc/src/arch @@ -0,0 +1 @@ +arch-arm \ No newline at end of file diff --git a/containers/posix/libc/src/arch-arm/eabi.c b/containers/posix/libc/src/arch-arm/eabi.c new file mode 100644 index 0000000..9bede4b --- /dev/null +++ b/containers/posix/libc/src/arch-arm/eabi.c @@ -0,0 +1,12 @@ + + +/* Dummies to keep Codesourcery 4.1.1 libgcc division exceptions silent. */ +void raise(void) +{ + +} + +void __aeabi_unwind_cpp_pr0(void) +{ +} + diff --git a/containers/posix/libc/src/arch-arm/uart.c b/containers/posix/libc/src/arch-arm/uart.c new file mode 100644 index 0000000..bf8adce --- /dev/null +++ b/containers/posix/libc/src/arch-arm/uart.c @@ -0,0 +1,191 @@ +/* + * Ties up platform's uart driver functions with generic API + * + * Copyright (C) 2007 Bahadir Balban + */ + +#include +#include + +/* UART-specific internal error codes */ +#define PL011_ERROR 1 +#define PL011_EAGAIN 2 + +/* Error status bits in receive status register */ +#define PL011_FE (1 << 0) +#define PL011_PE (1 << 1) +#define PL011_BE (1 << 2) +#define PL011_OE (1 << 3) + +/* Status bits in flag register */ +#define PL011_TXFE (1 << 7) +#define PL011_RXFF (1 << 6) +#define PL011_TXFF (1 << 5) +#define PL011_RXFE (1 << 4) +#define PL011_BUSY (1 << 3) +#define PL011_DCD (1 << 2) +#define PL011_DSR (1 << 1) +#define PL011_CTS (1 << 0) + +struct pl011_uart uart; + +int pl011_tx_char(char c) +{ + unsigned int val; + val = 0; + + read(val, PL011_UARTFR); + if(val & PL011_TXFF) { /* TX FIFO Full */ + return -PL011_EAGAIN; + } + write(c, PL011_UARTDR); + return 0; +} + +int pl011_rx_char(char * c) +{ + unsigned int data; + unsigned int val; + val = 0; + + read(val, PL011_UARTFR); + if(val & PL011_RXFE) { /* RX FIFO Empty */ + return -PL011_EAGAIN; + } + + read(data, PL011_UARTDR); + *c = (char) data; + + if((data >> 8) & 0xF) { /* There were errors */ + return -1; /* Signal error in xfer */ + } + return 0; /* No error return */ +} + + +/* + * Sets the baud rate in kbps. It is recommended to use + * standard rates such as: 1200, 2400, 3600, 4800, 7200, + * 9600, 14400, 19200, 28800, 38400, 57600 76800, 115200. + */ +void pl011_set_baudrate(unsigned int baud, unsigned int clkrate) +{ + const unsigned int uartclk = 24000000; /* 24Mhz clock fixed on pb926 */ + unsigned int val; + unsigned int ipart, fpart; + unsigned int remainder; + + remainder = 0; + ipart = 0; + fpart = 0; + val = 0; + + /* Use default pb926 rate if no rate is supplied */ + if(clkrate == 0) { + clkrate = uartclk; + } + if(baud > 115200 || baud < 1200) { + baud = 38400; /* Default rate. */ + } + /* 24000000 / (38400 * 16) */ + ipart = 39; + + write(ipart, PL011_UARTIBRD); + write(fpart, PL011_UARTFBRD); + + /* For the IBAUD and FBAUD to update, we need to + * write to UARTLCR_H because the 3 registers are + * actually part of a single register in hardware + * which only updates by a write to UARTLCR_H */ + read(val, PL011_UARTLCR_H); + write(val, PL011_UARTLCR_H); + return; + +} + + +/* Masks the irqs given in the flags bitvector. */ +void pl011_set_irq_mask(unsigned int flags) +{ + unsigned int val; + val = 0; + + if(flags > 0x3FF) { /* Invalid irqmask bitvector */ + return; + } + + read(val, PL011_UARTIMSC); + val |= flags; + write(val, PL011_UARTIMSC); + return; +} + + +/* Clears the irqs given in flags from masking */ +void pl011_clr_irq_mask(unsigned int flags) +{ + unsigned int val; + val = 0; + + if(flags > 0x3FF) { /* Invalid irqmask bitvector */ + return; + } + + read(val, PL011_UARTIMSC); + val &= ~flags; + write(val, PL011_UARTIMSC); + return; +} + +int pl011_initialise(struct pl011_uart * uart) +{ + + uart->frame_errors = 0; + uart->parity_errors = 0; + uart->break_errors = 0; + uart->overrun_errors = 0; + + /* Initialise data register for 8 bit data read/writes */ + pl011_set_word_width(8); + + /* Fifos are disabled because by default it is assumed the port + * will be used as a user terminal, and in that case the typed + * characters will only show up when fifos are flushed, rather than + * when each character is typed. We avoid this by not using fifos. + */ + pl011_disable_fifos(); + + /* Set default baud rate of 38400 */ + pl011_set_baudrate(38400, 24000000); + + /* Set default settings of 1 stop bit, no parity, no hw flow ctrl */ + pl011_set_stopbits(1); + pl011_parity_disable(); + + /* Disable all irqs */ + pl011_set_irq_mask(0x3FF); + + /* Enable rx, tx, and uart chip */ + pl011_tx_enable(); + pl011_rx_enable(); + pl011_uart_enable(); + + return 0; +} + +void uart_init() +{ + uart.base = PL011_BASE; + pl011_initialise(&uart); +} + +/* Generic uart function that lib/putchar.c expects to see implemented */ +void uart_putc(char c) +{ + int res; + /* Platform specific uart implementation */ + do { + res = pl011_tx_char(c); + } while (res < 0); +} + diff --git a/containers/posix/libc/src/format.c b/containers/posix/libc/src/format.c new file mode 100644 index 0000000..5018606 --- /dev/null +++ b/containers/posix/libc/src/format.c @@ -0,0 +1,543 @@ +/* + * Australian Public Licence B (OZPLB) + * + * Version 1-0 + * + * Copyright (c) 2004 University of New South Wales + * + * All rights reserved. + * + * Developed by: Operating Systems and Distributed Systems Group (DiSy) + * University of New South Wales + * http://www.disy.cse.unsw.edu.au + * + * Permission is granted by University of New South Wales, free of charge, to + * any person obtaining a copy of this software and any associated + * documentation files (the "Software") to deal with the Software without + * restriction, including (without limitation) the rights to use, copy, + * modify, adapt, merge, publish, distribute, communicate to the public, + * sublicense, and/or sell, lend or rent out copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimers. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimers in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of University of New South Wales, nor the names of its + * contributors, may be used to endorse or promote products derived + * from this Software without specific prior written permission. + * + * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT + * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND + * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS, + * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS + * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, + * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF + * ERRORS, WHETHER OR NOT DISCOVERABLE. + * + * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL + * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL + * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER + * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR + * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS + * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR + * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT, + * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN + * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER + * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS + * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS, + * DAMAGES OR OTHER LIABILITY. + * + * If applicable legislation implies representations, warranties, or + * conditions, or imposes obligations or liability on University of New South + * Wales or one of its contributors in respect of the Software that + * cannot be wholly or partly excluded, restricted or modified, the + * liability of University of New South Wales or the contributor is limited, to + * the full extent permitted by the applicable legislation, at its + * option, to: + * a. in the case of goods, any one or more of the following: + * i. the replacement of the goods or the supply of equivalent goods; + * ii. the repair of the goods; + * iii. the payment of the cost of replacing the goods or of acquiring + * equivalent goods; + * iv. the payment of the cost of having the goods repaired; or + * b. in the case of services: + * i. the supplying of the services again; or + * ii. the payment of the cost of having the services supplied again. + * + * The construction, validity and performance of this licence is governed + * by the laws in force in New South Wales, Australia. + */ +/* + Authors: Cristan Szmadja, Ben Leslie +*/ +#include +#include "stdio.h" +#include +#include +#include "format.h" +#define fputc putc +/* + * lookup tables for umaxtostr + */ +static const char xdigits[16] = "0123456789abcdef"; +static const char Xdigits[16] = "0123456789ABCDEF"; + +/* + * Convert an unsigned integer to a string of digits in the specified base. + * Buf should point to the END of the buffer: 22 characters is probably big + * enough. NO '\0' is appended to buf. + * + * If u == 0, NO digits are generated. The '0' is supplied by vfprintf using + * its default zero padding, except in certain rare situations (e.g., "%.0d"). + */ +static inline char * +umaxtostr(char *buf, uintmax_t u, int base, const char *digits) +{ + unsigned long u2; + + /* + * generate the digits in reverse order + */ +#if UINTMAX_MAX > ULONG_MAX + /* + * Uintmax_t arithmetic may be very slow. Use it only until the + * residual fits in an unsigned long. + */ + while (u > ULONG_MAX) { + *--buf = digits[u % base]; + u /= base; + } +#endif + for (u2 = u; u2 != 0UL;) { + *--buf = digits[u2 % base]; + u2 /= base; + } + return buf; +} + + +/* +This macro is *really* nasty. + +It isn't an inline function because it relies on variables declared in the +surrounding scope. Specifically: + stream_or_memory -> Indicates if we are going to a file, or memory + r -> The output counter + n -> max size + output -> output buffer (if going to memory) + stream -> output stream (if going to file) +*/ + +#define WRITE_CHAR(x) { \ + if (n != -1 && r == n) { \ + *output++ = '\0'; \ + overflowed = 1; \ + } \ + if (stream_or_memory) { \ + fputc(x, stream); \ + } else if (! overflowed) { \ + *output++ = x; \ + } \ + r++; \ +} \ + + + + +/* + * Print one formatted field. The length of s is len; any '\0's in s are + * IGNORED. The field may have an optional prefix ('+', ' ', '-', '0x', or + * '0X', packed into an unsigned int), and is padded appropriately to the + * specified width. If width < 0, the field is left-justified. + */ +static inline int +fprintf1(char *output, FILE *stream, bool stream_or_memory, size_t r, size_t n, + const char *s, int len, unsigned int prefix, + int prefixlen, int width, int prec, bool *over) +{ + size_t i; + size_t y = r; /* Keep a copy the starting value */ + bool overflowed = *over; /* Current start of overflow flag */ + + if (stream != NULL) + lock_stream(stream); + if (width - prec - prefixlen > 0) { + for (i = 0; i < width - prec - prefixlen; i++) { + WRITE_CHAR(' '); /* left-padding (if any) */ + } + } + + for (; prefix != 0; prefix >>= 8) { + WRITE_CHAR(prefix & 0377); /* prefix string */ + } + + for (i = 0; i < prec - len; i++) { + WRITE_CHAR('0'); /* zero-padding (if any) */ + } + + for (i = 0; i < len; i++) { + WRITE_CHAR(s[i]); /* actual string */ + } + + if (width < 0) { + while(y < -width) { + WRITE_CHAR(' '); /* right-padding (if any) */ + } + } + + *over = overflowed; /* Set overflow flag in the caller */ + + if (stream != NULL) + unlock_stream(stream); + return r - y; /* We return the number of chars added */ +} + +#include +/* + * parse printf format string + * if stream_or_memory == 1 -> use fputc, otherwise write to memory + * if n == -1, then don't check overflow + */ +int +format_string(char *output, FILE *stream, bool stream_or_memory, size_t n, + const char *fmt, va_list ap) +{ + bool alt, ljust, point, zeropad, overflowed = 0; + int lflags; /* 'h', 'j', 'l', 't', 'z' */ + unsigned int prefix; /* a very small string */ + int width, prec, base = 0, prefixlen; + size_t r, len; + const char *p, *s, *digits; + char buf[24], *const buf_end = buf + sizeof buf; + intmax_t d; + uintmax_t u = 0; + + r = 0; + if (stream != NULL) + lock_stream(stream); + for (p = fmt; *p != '\0'; p++) { + if (*p != '%') { + putc: + WRITE_CHAR(*p); + continue; + } + alt = false; + ljust = false; + point = false; + zeropad = false; + lflags = 0; + prefix = '\0'; + prefixlen = 0; + width = 0; + prec = 1; /* make sure 0 prints as "0" */ + digits = xdigits; + for (p++;; p++) { + again: + switch (*p) { + case '%': + goto putc; + case '#': + alt = true; + continue; + case '-': /* takes precedence over '0' */ + ljust = true; + continue; + case '0': + zeropad = true; + continue; + case '+': /* XXX should take precedence over + * ' ' */ + case ' ': + prefix = *p; + prefixlen = 1; + continue; + case '*': + width = va_arg(ap, int); + if (ljust) + width = -width; + continue; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + /* + * width = strtol(p, &p, 10), sort of + */ + width = *p - '0'; + for (p++; (unsigned int) (*p - '0') < 10; + p++) + width = width * 10 + (*p - '0'); + if (ljust) + width = -width; + goto again; /* don't increment p */ + case '.': + point = true; + if (*++p == '*') { + prec = va_arg(ap, int); + continue; + } else { + /* + * prec = strtol(p, &p, 10), sort + * of + */ + for (prec = 0; + (unsigned int) (*p - '0') < + 10; p++) + prec = + prec * 10 + (*p - '0'); + goto again; /* don't increment + * p */ + } + case 'h': + lflags--; + continue; + case 'L': + case 'l': + lflags++; + continue; + case 't': + case 'z': + lflags = 1; /* assume ptrdiff_t and + * size_t are long */ + continue; + case 'j': + lflags = 2; /* assume intmax_t is long + * long */ + continue; +#ifndef NO_FLOAT + case 'a': + case 'A': + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + /* + * NOT IMPLEMENTED + */ + switch (lflags) { + case 0: + va_arg(ap, double); + break; + case 1: + va_arg(ap, long double); + break; + default: + goto default_case; + } + break; +#endif /* !NO_FLOAT */ + case 'c': +#ifndef NO_WCHAR + /* + * NOT IMPLEMENTED + */ + if (lflags > 0) + va_arg(ap, wchar_t); + else +#endif + *(buf_end - 1) = va_arg(ap, int); + s = buf_end - 1; + len = 1; + goto common3; + case 'd': + case 'i': + switch (lflags) { + case -2: + // d = va_arg(ap, signed char); + d = va_arg(ap, int); + break; + case -1: + // d = va_arg(ap, short); + d = va_arg(ap, int); + break; + case 0: + d = va_arg(ap, int); + break; + case 1: + d = va_arg(ap, long); + break; +#ifndef NO_LONG_LONG + case 2: + d = va_arg(ap, long long); + break; +#endif + default: + goto default_case; + } + if (d < 0LL) { + /* + * safely negate d, even + * INTMAX_MIN + */ + u = -(uintmax_t) d; + prefix = '-'; /* override ' ' or + * '+' */ + prefixlen = 1; + } else { + u = d; + } + base = 10; + goto common2; + case 'n': + switch (lflags) { + case -2: + *va_arg(ap, signed char *) = r; + break; + case -1: + *va_arg(ap, short *) = r; + break; + case 0: + *va_arg(ap, int *) = r; + break; + case 1: + *va_arg(ap, long *) = r; + break; + case 2: + *va_arg(ap, long long *) = r; + break; + default: + goto default_case; + } + break; + case 'o': + base = 8; + goto common1; + case 'p': + u = (uintptr_t) va_arg(ap, const void *); + if (u != (uintptr_t) NULL) { + base = 16; + prec = 2 * sizeof(const void *); + prefix = '0' | 'x' << 8; + prefixlen = 2; + goto common2; + } else { + s = "(nil)"; + len = 5; + goto common3; + } + case 's': + s = va_arg(ap, const char *); + /* + * XXX left-justified strings are scanned + * twice + */ + if (point) { + /* + * len = min(prec, strlen(s)) + */ + for (len = 0; len < prec; len++) + if (s[len] == '\0') + break; + } else { + len = strlen(s); + } + goto common3; + case 'u': + base = 10; + goto common1; + case 'X': + digits = Xdigits; + /* + * FALLTHROUGH + */ + case 'x': + base = 16; + if (alt) { + prefix = '0' | *p << 8; + prefixlen = 2; + } + /* + * FALLTHROUGH + */ + common1: + /* + * common code for %o, %u, %X, and %x + */ + switch (lflags) { + case -2: + // u = va_arg(ap, unsigned char); + u = va_arg(ap, int); + break; + case -1: + // u = va_arg(ap, unsigned short); + u = va_arg(ap, int); + break; + case 0: + u = va_arg(ap, unsigned int); + break; + case 1: + u = va_arg(ap, unsigned long); + break; +#ifndef NO_LONG_LONG + case 2: + u = va_arg(ap, unsigned long long); + break; +#endif + default: + goto default_case; + } + /* + * FALLTHROUGH + */ + common2: + s = umaxtostr(buf_end, u, base, digits); + len = buf_end - s; + /* + * the field may overflow prec + */ + if (prec < len) + /* + * FALLTHOUGH + */ + common3: + prec = len; + if (zeropad && prec < width - prefixlen) + prec = width - prefixlen; + else if (alt && base == 8 && u != 0LL) + prec++; + + { + int tmp = fprintf1(output, stream, stream_or_memory, r, n, + s, len, prefix, + prefixlen, width, prec, &overflowed); + r += tmp; + output += tmp; + } + + break; + default: /* unrecognized conversion + * specifier */ + default_case: + /* + * print uninterpreted + */ + for (s = p - 1; *s != '%'; s--); + for (; s <= p; s++) { + WRITE_CHAR(*p); + } + break; + } + break; /* finished the conversion specifier */ + } + } + if (! stream_or_memory && ! overflowed) + *output++ = '\0'; + if (stream != NULL) + unlock_stream(stream); + return r; +} diff --git a/containers/posix/libc/src/format.h b/containers/posix/libc/src/format.h new file mode 100644 index 0000000..93503fd --- /dev/null +++ b/containers/posix/libc/src/format.h @@ -0,0 +1,86 @@ +/* + * Australian Public Licence B (OZPLB) + * + * Version 1-0 + * + * Copyright (c) 2004 National ICT Australia + * + * All rights reserved. + * + * Developed by: Embedded, Real-time and Operating Systems Program (ERTOS) + * National ICT Australia + * http://www.ertos.nicta.com.au + * + * Permission is granted by National ICT Australia, free of charge, to + * any person obtaining a copy of this software and any associated + * documentation files (the "Software") to deal with the Software without + * restriction, including (without limitation) the rights to use, copy, + * modify, adapt, merge, publish, distribute, communicate to the public, + * sublicense, and/or sell, lend or rent out copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimers. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimers in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of National ICT Australia, nor the names of its + * contributors, may be used to endorse or promote products derived + * from this Software without specific prior written permission. + * + * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT + * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND + * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS, + * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS + * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, + * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF + * ERRORS, WHETHER OR NOT DISCOVERABLE. + * + * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL + * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL + * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER + * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR + * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS + * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR + * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT, + * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN + * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER + * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS + * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS, + * DAMAGES OR OTHER LIABILITY. + * + * If applicable legislation implies representations, warranties, or + * conditions, or imposes obligations or liability on National ICT + * Australia or one of its contributors in respect of the Software that + * cannot be wholly or partly excluded, restricted or modified, the + * liability of National ICT Australia or the contributor is limited, to + * the full extent permitted by the applicable legislation, at its + * option, to: + * a. in the case of goods, any one or more of the following: + * i. the replacement of the goods or the supply of equivalent goods; + * ii. the repair of the goods; + * iii. the payment of the cost of replacing the goods or of acquiring + * equivalent goods; + * iv. the payment of the cost of having the goods repaired; or + * b. in the case of services: + * i. the supplying of the services again; or + * ii. the payment of the cost of having the services supplied again. + * + * The construction, validity and performance of this licence is governed + * by the laws in force in New South Wales, Australia. + */ +/* + Author: Ben Leslie +*/ +#ifndef _FORMAT_H_ +#define _FORMAT_H_ +#include +int format_string(char *output, FILE *stream, bool stream_or_memory, size_t n, const char *fmt, va_list ap); +#endif diff --git a/containers/posix/libc/src/printf.c b/containers/posix/libc/src/printf.c new file mode 100644 index 0000000..f472de8 --- /dev/null +++ b/containers/posix/libc/src/printf.c @@ -0,0 +1,446 @@ +/********************************************************************* + * + * Copyright (C) 2002-2004 Karlsruhe University + * + * File path: generic/printk.cc + * Description: Implementation of printf + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + ********************************************************************/ +#include /* for va_list, ... comes with gcc */ +#include + +/* FIXME: LICENSE LICENCE */ +typedef unsigned int word_t; + +extern void putc(const char c); +extern int print_tid (word_t val, word_t width, word_t precision, int adjleft); + + +/* convert nibble to lowercase hex char */ +#define hexchars(x) (((x) < 10) ? ('0' + (x)) : ('a' + ((x) - 10))) + +/** + * Print hexadecimal value + * + * @param val value to print + * @param width width in caracters + * @param precision minimum number of digits to apprear + * @param adjleft left adjust the value + * @param nullpad pad with leading zeros (when right padding) + * + * Prints a hexadecimal value with leading zeroes of given width + * using putc(), or if adjleft argument is given, print + * hexadecimal value with space padding to the right. + * + * @returns the number of charaters printed (should be same as width). + */ +int print_hex64(unsigned long long val, int width, int precision, int adjleft, int nullpad) +{ + int i, n = 0; + int nwidth = 0; + unsigned int high, low; + + high = val >> 32; + low = (unsigned int)val; + + // Find width of hexnumber + if (high) { + while ((high >> (4 * nwidth)) && ((unsigned) nwidth < 2 * sizeof (unsigned int))) + nwidth++; + nwidth += 32; + } else { + while ((low >> (4 * nwidth)) && ((unsigned) nwidth < 2 * sizeof (unsigned int))) + nwidth++; + } + + if (nwidth == 0) + nwidth = 1; + + // May need to increase number of printed digits + if (precision > nwidth) + nwidth = precision; + + // May need to increase number of printed characters + if (width == 0 && width < nwidth) + width = nwidth; + + // Print number with padding + if (high) + { + if (!adjleft) + for (i = width - nwidth; i > 0; i--, n++) + putc (nullpad ? '0' : ' '); + for (i = 4 * (nwidth - 33); i >= 0; i -= 4, n++) + putc (hexchars ((high >> i) & 0xF)); + if (adjleft) + for (i = width - nwidth; i > 0; i--, n++) + putc (' '); + width -= 32; + nwidth -= 32; + nullpad = 1; + } + if (! adjleft) + for (i = width - nwidth; i > 0; i--, n++) + putc (nullpad ? '0' : ' '); + for (i = 4 * (nwidth - 1); i >= 0; i -= 4, n++) + putc (hexchars ((low >> i) & 0xF)); + if (adjleft) + for (i = width - nwidth; i > 0; i--, n++) + putc (' '); + + return n; +} + +int print_hex_3arg(const word_t val, int width, int precision) +{ + long i, n = 0; + long nwidth = 0; + int adjleft = 0; + int nullpad = 0; + + // Find width of hexnumber + while ((val >> (4 * nwidth)) && (word_t) nwidth < 2 * sizeof (word_t)) + nwidth++; + + if (nwidth == 0) + nwidth = 1; + + // May need to increase number of printed digits + if (precision > nwidth) + nwidth = precision; + + // May need to increase number of printed characters + if (width == 0 && width < nwidth) + width = nwidth; + + // Print number with padding + if (! adjleft) + for (i = width - nwidth; i > 0; i--, n++) + putc (nullpad ? '0' : ' '); + for (i = 4 * (nwidth - 1); i >= 0; i -= 4, n++) + putc (hexchars ((val >> i) & 0xF)); + if (adjleft) + for (i = width - nwidth; i > 0; i--, n++) + putc (' '); + + return n; +} + +int print_hex_5arg(const word_t val, int width, + int precision, int adjleft, int nullpad) +{ + long i, n = 0; + long nwidth = 0; + + // Find width of hexnumber + while ((val >> (4 * nwidth)) && (word_t) nwidth < 2 * sizeof (word_t)) + nwidth++; + + if (nwidth == 0) + nwidth = 1; + + // May need to increase number of printed digits + if (precision > nwidth) + nwidth = precision; + + // May need to increase number of printed characters + if (width == 0 && width < nwidth) + width = nwidth; + + // Print number with padding + if (! adjleft) + for (i = width - nwidth; i > 0; i--, n++) + putc (nullpad ? '0' : ' '); + for (i = 4 * (nwidth - 1); i >= 0; i -= 4, n++) + putc (hexchars ((val >> i) & 0xF)); + if (adjleft) + for (i = width - nwidth; i > 0; i--, n++) + putc (' '); + + return n; +} +/** + * Print a string + * + * @param s zero-terminated string to print + * @param width minimum width of printed string + * + * Prints the zero-terminated string using putc(). The printed + * string will be right padded with space to so that it will be + * at least WIDTH characters wide. + * + * @returns the number of charaters printed. + */ +int print_string_3arg(const char * s, const int width, const int precision) +{ + int n = 0; + + for (;;) + { + if (*s == 0) + break; + + putc(*s++); + n++; + if (precision && n >= precision) + break; + } + + while (n < width) { putc(' '); n++; } + + return n; +} + +int print_string_1arg(const char * s) +{ + int n = 0; + int width = 0; + int precision = 0; + + for (;;) { + if (*s == 0) + break; + + putc(*s++); + n++; + if (precision && n >= precision) + break; + } + + while (n < width) { + putc(' '); + n++; + } + + return n; +} + + +/** + * Print hexadecimal value with a separator + * + * @param val value to print + * @param bits number of lower-most bits before which to + * place the separator + * @param sep the separator to print + * + * @returns the number of charaters printed. + */ +int print_hex_sep(const word_t val, const int bits, const char *sep) +{ + int n = 0; + + n = print_hex_3arg(val >> bits, 0, 0); + n += print_string_1arg(sep); + n += print_hex_3arg(val & ((1 << bits) - 1), 0, 0); + + return n; +} + + +/** + * Print decimal value + * + * @param val value to print + * @param width width of field + * @param pad character used for padding value up to width + * + * Prints a value as a decimal in the given WIDTH with leading + * whitespaces. + * + * @returns the number of characters printed (may be more than WIDTH) + */ +int print_dec(const word_t val, int width) +{ + word_t divisor; + int digits; + /* estimate number of spaces and digits */ + for (divisor = 1, digits = 1; val/divisor >= 10; divisor *= 10, digits++); + + /* print spaces */ + for ( ; digits < width; digits++ ) + putc(' '); + + /* print digits */ + do { + putc(((val/divisor) % 10) + '0'); + } while (divisor /= 10); + + /* report number of digits printed */ + return digits; +} + +/** + * Does the real printk work + * + * @param format_p pointer to format string + * @param args list of arguments, variable length + * + * Prints the given arguments as specified by the format string. + * Implements a subset of the well-known printf plus some L4-specifics. + * + * @returns the number of characters printed + */ +int do_printk(char* format_p, va_list args) +{ + const char* format = format_p; + int n = 0; + int i = 0; + int width = 8; + int precision = 0; + int adjleft = 0, nullpad = 0; + +#define arg(x) va_arg(args, x) + + /* sanity check */ + if (format == '\0') + { + return 0; + } + + while (*format) + { + switch (*(format)) + { + case '%': + width = precision = 0; + adjleft = nullpad = 0; + reentry: + switch (*(++format)) + { + /* modifiers */ + case '.': + for (format++; *format >= '0' && *format <= '9'; format++) + precision = precision * 10 + (*format) - '0'; + if (*format == 'w') + { + // Set precision to printsize of a hex word + precision = sizeof (word_t) * 2; + format++; + } + format--; + goto reentry; + case '0': + nullpad = (width == 0); + case '1'...'9': + width = width*10 + (*format)-'0'; + goto reentry; + case 'w': + // Set width to printsize of a hex word + width = sizeof (word_t) * 2; + goto reentry; + case '-': + adjleft = 0; + goto reentry; + case 'l': + goto reentry; + break; + case 'c': + putc(arg(int)); + n++; + break; + case 'm': /* microseconds */ + { + n += print_hex64(arg(unsigned long long), width, precision, + adjleft, nullpad); + break; + } + case 'd': + { + long val = arg(long); + if (val < 0) + { + putc('-'); + val = -val; + } + n += print_dec(val, width); + break; + } + case 'u': + n += print_dec(arg(long), width); + break; + case 'p': + precision = sizeof (word_t) * 2; + case 'x': + n += print_hex_5arg(arg(long), width, precision, adjleft, nullpad); + break; + case 's': + { + char* s = arg(char*); + if (s) + n += print_string_3arg(s, width, precision); + else + n += print_string_3arg("(null)", width, precision); + } + break; + + case 't': + case 'T': + // Do nothing for now. + //n += print_tid (arg (word_t), width, precision, adjleft); + break; + + case '%': + putc('%'); + n++; + format++; + continue; + default: + n += print_string_1arg("?"); + break; + }; + i++; + break; + default: + putc(*format); + n++; + break; + } + format++; + } + + return n; +} + +/** + * Flexible print function + * + * @param format string containing formatting and parameter type + * information + * @param ... variable list of parameters + * + * @returns the number of characters printed + */ +int printf(char *format, ...) +{ + va_list args; + int i; + + va_start(args, format); + i = do_printk(format, args); + va_end(args); + return i; +}; + + diff --git a/containers/posix/libc/src/putc.c b/containers/posix/libc/src/putc.c new file mode 100644 index 0000000..fc8c8c7 --- /dev/null +++ b/containers/posix/libc/src/putc.c @@ -0,0 +1,8 @@ +#include + +void putc(char c) +{ + if (c == '\n') + uart_putc('\r'); + uart_putc(c); +} diff --git a/containers/posix/libc/src/sprintf.c b/containers/posix/libc/src/sprintf.c new file mode 100644 index 0000000..e26c5d8 --- /dev/null +++ b/containers/posix/libc/src/sprintf.c @@ -0,0 +1,107 @@ +/* + * Australian Public Licence B (OZPLB) + * + * Version 1-0 + * + * Copyright (c) 2004 National ICT Australia + * + * All rights reserved. + * + * Developed by: Embedded, Real-time and Operating Systems Program (ERTOS) + * National ICT Australia + * http://www.ertos.nicta.com.au + * + * Permission is granted by National ICT Australia, free of charge, to + * any person obtaining a copy of this software and any associated + * documentation files (the "Software") to deal with the Software without + * restriction, including (without limitation) the rights to use, copy, + * modify, adapt, merge, publish, distribute, communicate to the public, + * sublicense, and/or sell, lend or rent out copies of the Software, and + * to permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimers. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimers in the documentation and/or other materials provided + * with the distribution. + * + * * Neither the name of National ICT Australia, nor the names of its + * contributors, may be used to endorse or promote products derived + * from this Software without specific prior written permission. + * + * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT + * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND + * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS, + * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS + * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE, + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, + * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF + * ERRORS, WHETHER OR NOT DISCOVERABLE. + * + * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL + * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL + * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER + * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR + * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS + * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR + * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT, + * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN + * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER + * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS + * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS, + * DAMAGES OR OTHER LIABILITY. + * + * If applicable legislation implies representations, warranties, or + * conditions, or imposes obligations or liability on National ICT + * Australia or one of its contributors in respect of the Software that + * cannot be wholly or partly excluded, restricted or modified, the + * liability of National ICT Australia or the contributor is limited, to + * the full extent permitted by the applicable legislation, at its + * option, to: + * a. in the case of goods, any one or more of the following: + * i. the replacement of the goods or the supply of equivalent goods; + * ii. the repair of the goods; + * iii. the payment of the cost of replacing the goods or of acquiring + * equivalent goods; + * iv. the payment of the cost of having the goods repaired; or + * b. in the case of services: + * i. the supplying of the services again; or + * ii. the payment of the cost of having the services supplied again. + * + * The construction, validity and performance of this licence is governed + * by the laws in force in New South Wales, Australia. + */ +/* +Author: Ben Leslie +*/ +#ifndef NULL +#define NULL 0 +#endif + +#include +#include "format.h" + +#include + +int +vsprintf(char *s, const char *format, va_list arg) +{ + return format_string(s, NULL, 0, -1, format, arg); +} +int +sprintf(char *s, const char *format, ...) +{ + int ret; + va_list ap; + + va_start(ap, format); + ret = vsprintf(s, format, ap); + va_end(ap); + return ret; +} + diff --git a/containers/posix/libc/src/string.c b/containers/posix/libc/src/string.c new file mode 100644 index 0000000..8de669e --- /dev/null +++ b/containers/posix/libc/src/string.c @@ -0,0 +1,84 @@ +#include + +int strlen(const char *s) +{ + const char *p; + + for (p = s; *p != '\0'; p++); + return p - s; +} + +char *strcpy(char *to, const char *from) +{ + char *t = to; + + while ((*to++ = *from++) != '\0') + ; + return t; +} + +void *memset(void *p, int c, int size) +{ + char ch; + char *pp; + + pp = (char *)p; + ch = (char)c; + + for (int i = 0; i < size; i++) { + *pp++ = ch; + } + return p; +} + +void *memcpy(void *d, void *s, int size) +{ + char *dst = (char *)d; + char *src = (char *)s; + + for (int i = 0; i < size; i++) { + *dst = *src; + dst++; + src++; + } + return d; +} + + +int strcmp(const char *s1, const char *s2) +{ + unsigned int i = 0; + int d; + + while(1) { + d = (unsigned char)s1[i] - (unsigned char)s2[i]; + if (d != 0 || s1[i] == '\0') + return d; + i++; + } +} + +/* + * Copies string pointed by @from to string pointed by @to. + * + * If count is greater than the length of string in @from, + * pads rest of the locations with null. + */ +char *strncpy(char *to, const char *from, int count) +{ + char *temp = to; + + while (count) { + *temp = *from; + + /* + * Stop updating from if null + * terminator is reached. + */ + if (*from) + from++; + temp++; + count--; + } + return to; +} diff --git a/containers/posix/libl4/include/l4lib/arch-arm/syslib.h b/containers/posix/libl4/include/l4lib/arch-arm/syslib.h index cfba52a..5ed0f66 100644 --- a/containers/posix/libl4/include/l4lib/arch-arm/syslib.h +++ b/containers/posix/libl4/include/l4lib/arch-arm/syslib.h @@ -7,7 +7,7 @@ #ifndef __L4LIB_SYSLIB_H__ #define __L4LIB_SYSLIB_H__ -#include +#include #include #include diff --git a/containers/posix/mm0/SConscript b/containers/posix/mm0/SConscript index 5c1ca07..4d1292e 100644 --- a/containers/posix/mm0/SConscript +++ b/containers/posix/mm0/SConscript @@ -19,6 +19,6 @@ Import('environment', 'previousImage') -program = environment['buildTask']('mm0', Glob('*.c') + [Glob(directory + '/*.c') for directory in [ 'src', 'src/lib', 'src/lib/elf', 'src/arch-' + environment['ARCH']]], environment, previousImage) +program = environment['buildTask']('mm0', Glob('*.c') + [Glob(directory + '/*.[cS]') for directory in [ 'src', 'src/lib', 'src/lib/elf', 'src/arch-' + environment['ARCH']]], environment, previousImage) Return('program') diff --git a/containers/posix/mm0/container.c b/containers/posix/mm0/container.c index 2b7d1f2..598d520 100644 --- a/containers/posix/mm0/container.c +++ b/containers/posix/mm0/container.c @@ -16,9 +16,13 @@ */ void main(void); +void uart_init(void); void __container_init(void) { + /* Initialize uarts */ + uart_init(); + /* Generic L4 initialisation */ __l4_init(); diff --git a/containers/posix/mm0/include/file.h b/containers/posix/mm0/include/file.h index f14565f..19caf83 100644 --- a/containers/posix/mm0/include/file.h +++ b/containers/posix/mm0/include/file.h @@ -6,6 +6,10 @@ #include #include +#define SEEK_CUR 0 +#define SEEK_END 1 +#define SEEK_SET 2 + int vfs_read(unsigned long vnum, unsigned long f_offset, unsigned long npages, void *pagebuf); int vfs_write(unsigned long vnum, unsigned long f_offset, unsigned long npages, diff --git a/containers/posix/mm0/include/linker.lds b/containers/posix/mm0/include/linker.lds index ffd56a2..ae99198 100644 --- a/containers/posix/mm0/include/linker.lds +++ b/containers/posix/mm0/include/linker.lds @@ -25,7 +25,7 @@ SECTIONS { . = virtual_base; _start_text = .; - .text : AT (ADDR(.text) - pager_offset) { crt0.o(.text) *(.text) } + .text : AT (ADDR(.text) - pager_offset) { *(.text.head) *(.text) } /* rodata is needed else your strings will link at physical! */ .rodata : AT (ADDR(.rodata) - pager_offset) { *(.rodata) } .rodata1 : AT (ADDR(.rodata1) - pager_offset) { *(.rodata1) } diff --git a/containers/posix/mm0/main.c b/containers/posix/mm0/main.c index fe32503..8ada25e 100644 --- a/containers/posix/mm0/main.c +++ b/containers/posix/mm0/main.c @@ -168,9 +168,9 @@ void handle_requests(void) } default: printf("%s: Unrecognised ipc tag (%d) " - "received from (%d). Full mr reading: " + "received from (%lu). Full mr reading: " "%u, %u, %u, %u, %u, %u. Ignoring.\n", - __TASKNAME__, tag, sender, read_mr(0), + __TASKNAME__, tag, (unsigned long)senderid, read_mr(0), read_mr(1), read_mr(2), read_mr(3), read_mr(4), read_mr(5)); } diff --git a/containers/posix/mm0/src/arch-arm/crt0.S b/containers/posix/mm0/src/arch-arm/crt0.S new file mode 100644 index 0000000..a390ee9 --- /dev/null +++ b/containers/posix/mm0/src/arch-arm/crt0.S @@ -0,0 +1,12 @@ + +.section .text.head +.global _start; +.type _start,function; +.align; + +_start: + ldr sp, =__stack + bl __container_init +1: + b 1b + diff --git a/containers/posix/mm0/src/arch-arm/mm.c b/containers/posix/mm0/src/arch-arm/mm.c index 5781fee..8a30cb3 100644 --- a/containers/posix/mm0/src/arch-arm/mm.c +++ b/containers/posix/mm0/src/arch-arm/mm.c @@ -4,6 +4,7 @@ #include #include #include +#include /* Extracts generic protection flags from architecture-specific pte */ unsigned int vm_prot_flags(pte_t pte) diff --git a/containers/posix/mm0/src/arch/crt0.S b/containers/posix/mm0/src/arch/crt0.S new file mode 100644 index 0000000..a390ee9 --- /dev/null +++ b/containers/posix/mm0/src/arch/crt0.S @@ -0,0 +1,12 @@ + +.section .text.head +.global _start; +.type _start,function; +.align; + +_start: + ldr sp, =__stack + bl __container_init +1: + b 1b + diff --git a/containers/posix/mm0/src/bootm.c b/containers/posix/mm0/src/bootm.c index cf7a602..74d4b98 100644 --- a/containers/posix/mm0/src/bootm.c +++ b/containers/posix/mm0/src/bootm.c @@ -13,7 +13,7 @@ #include #include INC_GLUE(memory.h) -#include +#include /* All memory allocated here is discarded after boot */ diff --git a/containers/posix/mm0/src/capability.c b/containers/posix/mm0/src/capability.c index b89acb9..b1f218e 100644 --- a/containers/posix/mm0/src/capability.c +++ b/containers/posix/mm0/src/capability.c @@ -11,6 +11,7 @@ #include #include /* TODO: Move this to API */ #include +#include struct cap_list capability_list; diff --git a/containers/posix/mm0/src/file.c b/containers/posix/mm0/src/file.c index 0b8f0d5..f6472ba 100644 --- a/containers/posix/mm0/src/file.c +++ b/containers/posix/mm0/src/file.c @@ -348,7 +348,7 @@ int read_file_pages(struct vm_file *vmfile, unsigned long pfn_start, f_offset); if (IS_ERR(page)) { printf("%s: %s:Could not read page %d " - "from file with vnum: 0x%x\n", __TASKNAME__, + "from file with vnum: 0x%lx\n", __TASKNAME__, __FUNCTION__, f_offset, vm_file_to_vnum(vmfile)); return (int)page; } @@ -460,7 +460,7 @@ int write_file_pages(struct vm_file *f, unsigned long pfn_start, err = f->vm_obj.pager->ops.page_out(&f->vm_obj, f_offset); if (err < 0) { printf("%s: %s:Could not write page %d " - "to file with vnum: 0x%x\n", __TASKNAME__, + "to file with vnum: 0x%lx\n", __TASKNAME__, __FUNCTION__, f_offset, vm_file_to_vnum(f)); return err; } diff --git a/containers/posix/mm0/src/lib/addr.c b/containers/posix/mm0/src/lib/addr.c index d7c7733..8131fa5 100644 --- a/containers/posix/mm0/src/lib/addr.c +++ b/containers/posix/mm0/src/lib/addr.c @@ -9,7 +9,7 @@ #include #include INC_GLUE(memory.h) #include -#include +#include /* * Initializes an address pool, but uses an already diff --git a/containers/posix/mm0/src/lib/bit.c b/containers/posix/mm0/src/lib/bit.c index 84750e3..9eaaf5c 100644 --- a/containers/posix/mm0/src/lib/bit.c +++ b/containers/posix/mm0/src/lib/bit.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include INC_GLUE(memory.h) /* Emulation of ARM's CLZ (count leading zeroes) instruction */ diff --git a/containers/posix/mm0/src/lib/elf/elf.c b/containers/posix/mm0/src/lib/elf/elf.c index 3f6a62f..179b6e4 100644 --- a/containers/posix/mm0/src/lib/elf/elf.c +++ b/containers/posix/mm0/src/lib/elf/elf.c @@ -10,7 +10,7 @@ #include #include #include - +#include int elf_probe(struct elf_header *header) { diff --git a/containers/posix/mm0/src/lib/idpool.c b/containers/posix/mm0/src/lib/idpool.c index 9d1f3df..384d15c 100644 --- a/containers/posix/mm0/src/lib/idpool.c +++ b/containers/posix/mm0/src/lib/idpool.c @@ -7,7 +7,7 @@ #include #include #include INC_GLUE(memory.h) -#include +#include #include struct id_pool *id_pool_new_init(int totalbits) diff --git a/containers/posix/mm0/src/lib/malloc.c b/containers/posix/mm0/src/lib/malloc.c index 13b36ef..cfd303a 100644 --- a/containers/posix/mm0/src/lib/malloc.c +++ b/containers/posix/mm0/src/lib/malloc.c @@ -18,6 +18,7 @@ Messages that indicate a software error will contain three asterisks (***). *****************************************************************************/ #include /* memcpy(), memset() */ #include /* printf() */ +#include #include #define _32BIT 1 diff --git a/containers/posix/mm0/src/mmap.c b/containers/posix/mm0/src/mmap.c index 5acb0e4..857385c 100644 --- a/containers/posix/mm0/src/mmap.c +++ b/containers/posix/mm0/src/mmap.c @@ -239,8 +239,8 @@ void *do_mmap(struct vm_file *mapfile, unsigned long file_offset, /* Get total file pages, check if mapping is within file size */ file_npages = __pfn(page_align_up(mapfile->length)); if (npages > file_npages - file_offset) { - printf("%s: Trying to map %d pages from page %d, " - "but file length is %d\n", __FUNCTION__, + printf("%s: Trying to map %d pages from page %lu, " + "but file length is %lu\n", __FUNCTION__, npages, file_offset, file_npages); return PTR_ERR(-EINVAL); } diff --git a/containers/posix/mm0/src/pagers.c b/containers/posix/mm0/src/pagers.c index ed3512f..fd46d59 100644 --- a/containers/posix/mm0/src/pagers.c +++ b/containers/posix/mm0/src/pagers.c @@ -71,8 +71,8 @@ int file_page_out(struct vm_object *vm_obj, unsigned long page_offset) /* Check first if the file has such a page at all */ if (__pfn(page_align_up(f->length) <= page_offset)) { - printf("%s: %s: Trying to look up page %d, but file length " - "is %d bytes.\n", __TASKNAME__, __FUNCTION__, + printf("%s: %s: Trying to look up page %lu, but file length " + "is %lu bytes.\n", __TASKNAME__, __FUNCTION__, page_offset, f->length); BUG(); } @@ -123,8 +123,8 @@ struct page *file_page_in(struct vm_object *vm_obj, unsigned long page_offset) /* Check first if the file has such a page at all */ if (__pfn(page_align_up(f->length) <= page_offset)) { - printf("%s: %s: Trying to look up page %d, but file length " - "is %d bytes.\n", __TASKNAME__, __FUNCTION__, + printf("%s: %s: Trying to look up page %lu, but file length " + "is %lu bytes.\n", __TASKNAME__, __FUNCTION__, page_offset, f->length); BUG(); } @@ -253,8 +253,8 @@ struct page *bootfile_page_in(struct vm_object *vm_obj, /* Check first if the file has such a page at all */ if (__pfn(page_align_up(boot_file->length) <= offset)) { - printf("%s: %s: Trying to look up page %d, but file length " - "is %d bytes.\n", __TASKNAME__, __FUNCTION__, + printf("%s: %s: Trying to look up page %lu, but file length " + "is %lu bytes.\n", __TASKNAME__, __FUNCTION__, offset, boot_file->length); BUG(); } diff --git a/containers/posix/mm0/src/test.c b/containers/posix/mm0/src/test.c index e04ab66..db43b30 100644 --- a/containers/posix/mm0/src/test.c +++ b/containers/posix/mm0/src/test.c @@ -10,6 +10,7 @@ #include #include #include +#include struct vm_statistics { int tasks; /* All tasks counted on the system */ diff --git a/containers/posix/mm0/src/utcb.c b/containers/posix/mm0/src/utcb.c index 6add67c..2b87386 100644 --- a/containers/posix/mm0/src/utcb.c +++ b/containers/posix/mm0/src/utcb.c @@ -10,6 +10,7 @@ #include #include #include +#include /* * UTCB management in Codezero @@ -140,7 +141,7 @@ out: if (IS_ERR(err = do_mmap(0, 0, task, slot, VMA_ANONYMOUS | VMA_PRIVATE | VMA_FIXED | VM_READ | VM_WRITE, 1))) { - printf("UTCB: mmapping failed with %d\n", err); + printf("UTCB: mmapping failed with %p\n", err); return (int)err; } } diff --git a/containers/posix/mm0/src/vm_object.c b/containers/posix/mm0/src/vm_object.c index 23ee304..515c839 100644 --- a/containers/posix/mm0/src/vm_object.c +++ b/containers/posix/mm0/src/vm_object.c @@ -9,6 +9,7 @@ #include #include #include +#include /* Global list of all in-memory files on the system */ struct global_list global_vm_files = { diff --git a/containers/posix/test0/SConscript b/containers/posix/test0/SConscript index a7e86b7..d222219 100644 --- a/containers/posix/test0/SConscript +++ b/containers/posix/test0/SConscript @@ -52,7 +52,7 @@ SECTIONS { . = virtual_base; _start_text = .; - .text : AT (ADDR(.text) - offset) { crt0.o(.text) *(.text) } + .text : AT (ADDR(.text) - offset) { *(.text.init) *(.text) } /* rodata is needed else your strings will link at physical! */ .rodata : AT (ADDR(.rodata) - offset) { *(.rodata) } .rodata1 : AT (ADDR(.rodata1) - offset) { *(.rodata1) } @@ -78,10 +78,10 @@ testTaskEnvironment.Append(CPPPATH=['#' + posixServicesDirectory +'libposix/incl testExecLinkerScript = Command('#build/' + posixServicesDirectory + taskName + '/include/test_exec_linker.lds', testTaskEnvironment['physicalBaseLinkerScript'], createTestExecLinkerScript) testExecEnvironment = testTaskEnvironment.Clone() testExecEnvironment.Append(LINKFLAGS=['-T' + testExecLinkerScript[0].path]) -testExec = testExecEnvironment.Program('test_exec', Glob('src/test_exec/*.c') + ['#' + environment['userspace_crt0'][0].name]) +testExec = testExecEnvironment.Program('test_exec', Glob('src/test_exec/*.[cS]')) Depends(testExec, testExecLinkerScript) testExecS = Command('#build/' + posixServicesDirectory + taskName + '/test_exec.S', testExec, createTestExecS) -program = testTaskEnvironment['buildTask'](taskName, Glob('*.c') + Glob('src/*.c') + testExecS, testTaskEnvironment, previousImage) +program = testTaskEnvironment['buildTask'](taskName, Glob('*.c') + Glob('src/*.[cS]') + testExecS, testTaskEnvironment, previousImage) Depends(program, testExec) Return('program') diff --git a/containers/posix/test0/include/linker.lds b/containers/posix/test0/include/linker.lds index f1c0c3e..5da024e 100644 --- a/containers/posix/test0/include/linker.lds +++ b/containers/posix/test0/include/linker.lds @@ -26,7 +26,7 @@ SECTIONS { . = virtual_base; _start_text = .; - .text : AT (ADDR(.text) - offset) { crt0.o(.text) *(.text) } + .text : AT (ADDR(.text) - offset) { *(.text.head) *(.text) } /* rodata is needed else your strings will link at physical! */ .rodata : AT (ADDR(.rodata) - offset) { *(.rodata) } .rodata1 : AT (ADDR(.rodata1) - offset) { *(.rodata1) } diff --git a/containers/posix/test0/include/tests.h b/containers/posix/test0/include/tests.h index e6e313f..5d67d15 100644 --- a/containers/posix/test0/include/tests.h +++ b/containers/posix/test0/include/tests.h @@ -3,13 +3,14 @@ #define __TASKNAME__ "test0" -//#define TEST_VERBOSE_PRINT +#define TEST_VERBOSE_PRINT #if defined (TEST_VERBOSE_PRINT) #define test_printf(...) printf(__VA_ARGS__) #else #define test_printf(...) #endif +#include #include extern pid_t parent_of_all; diff --git a/containers/posix/test0/src/clonetest.c b/containers/posix/test0/src/clonetest.c index a0f50d2..56c14cb 100644 --- a/containers/posix/test0/src/clonetest.c +++ b/containers/posix/test0/src/clonetest.c @@ -2,6 +2,7 @@ * Clone test. */ #include +#include #include #include #include diff --git a/containers/posix/test0/src/crt0.S b/containers/posix/test0/src/crt0.S new file mode 100644 index 0000000..a390ee9 --- /dev/null +++ b/containers/posix/test0/src/crt0.S @@ -0,0 +1,12 @@ + +.section .text.head +.global _start; +.type _start,function; +.align; + +_start: + ldr sp, =__stack + bl __container_init +1: + b 1b + diff --git a/containers/posix/test0/src/dirtest.c b/containers/posix/test0/src/dirtest.c index a091248..ea8ca6f 100644 --- a/containers/posix/test0/src/dirtest.c +++ b/containers/posix/test0/src/dirtest.c @@ -11,12 +11,13 @@ #include #include #include +#include #define DENTS_TOTAL 50 void print_fsize(struct stat *s) { - printf("%d", s->st_size); + printf("%lu", s->st_size); } void print_flink(struct stat *s) diff --git a/containers/posix/test0/src/exectest.c b/containers/posix/test0/src/exectest.c index 9b9d945..af26038 100644 --- a/containers/posix/test0/src/exectest.c +++ b/containers/posix/test0/src/exectest.c @@ -10,6 +10,7 @@ #include #include #include +#include extern char _start_test_exec[]; extern char _end_test_exec[]; diff --git a/containers/posix/test0/src/fileio.c b/containers/posix/test0/src/fileio.c index b5aabe3..e1bede3 100644 --- a/containers/posix/test0/src/fileio.c +++ b/containers/posix/test0/src/fileio.c @@ -7,6 +7,7 @@ #include #include #include +#include int fileio(void) { diff --git a/containers/posix/test0/src/forktest.c b/containers/posix/test0/src/forktest.c index 204b83e..54c30b4 100644 --- a/containers/posix/test0/src/forktest.c +++ b/containers/posix/test0/src/forktest.c @@ -7,6 +7,7 @@ #include #include #include +#include int global = 0; diff --git a/containers/posix/test0/src/mmaptest.c b/containers/posix/test0/src/mmaptest.c index 5ff6230..9550481 100644 --- a/containers/posix/test0/src/mmaptest.c +++ b/containers/posix/test0/src/mmaptest.c @@ -14,6 +14,7 @@ #include #include #include +#include #define PAGE_SIZE 0x1000 diff --git a/containers/posix/test0/src/shmtest.c b/containers/posix/test0/src/shmtest.c index edf4d11..713fef6 100644 --- a/containers/posix/test0/src/shmtest.c +++ b/containers/posix/test0/src/shmtest.c @@ -22,7 +22,7 @@ int shmtest(void) test_printf("Initiating shmget()\n"); for (int i = 0; i < 2; i++) { if ((shmids[i] = shmget(keys[i], 27, IPC_CREAT | 0666)) < 0) { - test_printf("SHMGET", errno); + test_printf("SHMGET: %d", errno); goto out_err; } else test_printf("SHMID returned: %d\n", shmids[i]); @@ -30,7 +30,7 @@ int shmtest(void) test_printf("Now shmat()\n"); for (int i = 0; i < 2; i++) { if ((int)(bases[i] = shmat(shmids[i], NULL, 0)) == -1) { - test_printf("SHMAT", errno); + test_printf("SHMAT: %d", errno); goto out_err; } else test_printf("SHM base address returned: %p\n", bases[i]); @@ -42,7 +42,7 @@ int shmtest(void) test_printf("Now shmdt()\n"); for (int i = 0; i < 2; i++) { if (shmdt(bases[i]) < 0) { - test_printf("SHMDT", errno); + test_printf("SHMDT: %d", errno); goto out_err; } else test_printf("SHM detached OK.\n"); diff --git a/containers/posix/test0/src/test_exec/crt0.S b/containers/posix/test0/src/test_exec/crt0.S new file mode 100644 index 0000000..a390ee9 --- /dev/null +++ b/containers/posix/test0/src/test_exec/crt0.S @@ -0,0 +1,12 @@ + +.section .text.head +.global _start; +.type _start,function; +.align; + +_start: + ldr sp, =__stack + bl __container_init +1: + b 1b + diff --git a/containers/posix/test0/src/test_exec/test_exec.c b/containers/posix/test0/src/test_exec/test_exec.c index b1287b7..5e40cb5 100644 --- a/containers/posix/test0/src/test_exec/test_exec.c +++ b/containers/posix/test0/src/test_exec/test_exec.c @@ -26,7 +26,7 @@ void main(void) { wait_pager(0); if (getpid() == 2) { - printf("EXECVE TEST -- PASSED --\n", getpid()); + printf("EXECVE TEST -- PASSED --\n"); printf("\nThread (%d): Continues to sync with the pager...\n\n", getpid()); while (1) wait_pager(0);