void __libc_init_common(uintptr_t *elfdata) { int argc = *elfdata; char** argv = (char**)(elfdata + 1); char** envp = argv + argc + 1; pthread_attr_t thread_attr; static pthread_internal_t thread; static void* tls_area[BIONIC_TLS_SLOTS]; /* setup pthread runtime and maint thread descriptor */ unsigned stacktop = (__get_sp() & ~(PAGE_SIZE - 1)) + PAGE_SIZE; unsigned stacksize = 128 * 1024; unsigned stackbottom = stacktop - stacksize; pthread_attr_init(&thread_attr); pthread_attr_setstack(&thread_attr, (void*)stackbottom, stacksize); _init_thread(&thread, gettid(), &thread_attr, (void*)stackbottom); __init_tls(tls_area, &thread); /* clear errno - requires TLS area */ errno = 0; /* set program name */ __progname = argv[0] ? argv[0] : "<unknown>"; /* setup environment pointer */ environ = envp; /* setup system properties - requires environment */ __system_properties_init(); }
/* Init TLS for the initial thread. Called by the linker _before_ libc is mapped * in memory. Beware: all writes to libc globals from this function will * apply to linker-private copies and will not be visible from libc later on. * * Note: this function creates a pthread_internal_t for the initial thread and * stores the pointer in TLS, but does not add it to pthread's thread list. This * has to be done later from libc itself (see __libc_init_common). * * This function also stores a pointer to the kernel argument block in a TLS slot to be * picked up by the libc constructor. */ void __libc_init_tls(KernelArgumentBlock& args) { __libc_auxv = args.auxv; static void* tls[BIONIC_TLS_SLOTS]; static pthread_internal_t main_thread; main_thread.tls = tls; // Tell the kernel to clear our tid field when we exit, so we're like any other pthread. // As a side-effect, this tells us our pid (which is the same as the main thread's tid). main_thread.tid = __set_tid_address(&main_thread.tid); main_thread.set_cached_pid(main_thread.tid); // Work out the extent of the main thread's stack. uintptr_t stack_top = (__get_sp() & ~(PAGE_SIZE - 1)) + PAGE_SIZE; size_t stack_size = get_main_thread_stack_size(); void* stack_bottom = reinterpret_cast<void*>(stack_top - stack_size); // We don't want to free the main thread's stack even when the main thread exits // because things like environment variables with global scope live on it. pthread_attr_init(&main_thread.attr); pthread_attr_setstack(&main_thread.attr, stack_bottom, stack_size); main_thread.attr.flags = PTHREAD_ATTR_FLAG_USER_ALLOCATED_STACK | PTHREAD_ATTR_FLAG_MAIN_THREAD; __init_thread(&main_thread, false); __init_tls(&main_thread); __set_tls(main_thread.tls); tls[TLS_SLOT_BIONIC_PREINIT] = &args; __init_alternate_signal_stack(&main_thread); }
PRIVATE s32 idle_task(u32 arg) { unlock_irq(); /* kick off the system, will switch to the main_task */ while(1) { #if 0 PRINT_INFO("in %s %d cpu_mode: %s; lr: 0x%x; sp: 0x%x; cpsr: 0x%x\n", __func__, __LINE__, get_cpu_mode(NULL), __get_lr(), __get_sp(), __get_cpsr()); #endif /* mdelay(100000); */ #if 0 PRINT_INFO("in %s %d cpu_mode: %s; lr: 0x%x; sp: 0x%x; cpsr: 0x%x\n", __func__, __LINE__, get_cpu_mode(NULL), __get_lr(), __get_sp(), __get_cpsr()); #endif } return 0; }
static void test_task() { unsigned long long t; unsigned int th, bh; unsigned int v; int fd; char *buf = "abcdefABCDEFabcdefABCDEFabcdefABCDEFabcdefABCDEFabcdef" "ABCDEFabcdabcdefABCDEFabcdefABCDEFabcdefABCDEFabcdefABCDEF" "abcdefABCDEFabcd"; sleep(3); printk("\nstart write test %x %x\n", current, current->addr); //if ((fd = open("/test_write", O_CREATE | O_RDWR)) <= 0) { if ((fd = open("/test_write", O_RDWR)) == -ERR_PATH) { if ((fd = open("/test_write", O_CREATE | O_RDWR)) < 0) { printk("FAILED to create\n"); goto out; } int i; //for (i = 0; i < 5000; i++) { for (i = 0; i < 50; i++) { if (write(fd, buf, 128) <= 0) break; printf("%d written\n", (i+1) * 128); } } close(fd); out: if ((fd = open("/dev_overlap", O_CREATE)) > 0) close(fd); printf("\nend write test\n"); printf("test()\n"); printf("sp : %x, lr : %x\n", __get_sp(), __get_lr()); while (1) { t = get_systick64(); th = t >> 32; bh = t; dmb(); v = systick; printf("%08x ", v); printf("%08x", th); printf("%08x %d (%d sec)\n", bh, v, v/HZ); sleep(1); } }
/* Initializes memory allocation framework. * This routine is called from __libc_init routines implemented * in libc_init_static.c and libc_init_dynamic.c files. */ void malloc_debug_init(void) { /* We need to initialize malloc iff we implement here custom * malloc routines (i.e. USE_DL_PREFIX is defined) for libc.so */ #if defined(USE_DL_PREFIX) && !defined(LIBC_STATIC) stack_start = (__get_sp() & ~(4*1024 - 1)) + 4*1024; unsigned stacksize = 128 * 1024; stack_end = stack_start - stacksize; stack_end -= 4 * 1024; if (pthread_once(&malloc_init_once_ctl, malloc_init_impl)) { error_log("Unable to initialize malloc_debug component."); } #endif // USE_DL_PREFIX && !LIBC_STATIC }
/* Init TLS for the initial thread. Called by the linker _before_ libc is mapped * in memory. Beware: all writes to libc globals from this function will * apply to linker-private copies and will not be visible from libc later on. * * Note: this function creates a pthread_internal_t for the initial thread and * stores the pointer in TLS, but does not add it to pthread's gThreadList. This * has to be done later from libc itself (see __libc_init_common). * * This function also stores the elf_data argument in a specific TLS slot to be later * picked up by the libc constructor. */ void __libc_init_tls(unsigned** elf_data) { unsigned stack_top = (__get_sp() & ~(PAGE_SIZE - 1)) + PAGE_SIZE; unsigned stack_size = 128 * 1024; unsigned stack_bottom = stack_top - stack_size; pthread_attr_t thread_attr; pthread_attr_init(&thread_attr); pthread_attr_setstack(&thread_attr, (void*) stack_bottom, stack_size); static pthread_internal_t thread; _init_thread(&thread, gettid(), &thread_attr, (void*) stack_bottom, false); static void* tls_area[BIONIC_TLS_SLOTS]; __init_tls(tls_area, &thread); tls_area[TLS_SLOT_BIONIC_PREINIT] = elf_data; }
/* Init TLS for the initial thread. Called by the linker _before_ libc is mapped * in memory. Beware: all writes to libc globals from this function will * apply to linker-private copies and will not be visible from libc later on. * * Note: this function creates a pthread_internal_t for the initial thread and * stores the pointer in TLS, but does not add it to pthread's gThreadList. This * has to be done later from libc itself (see __libc_init_common). * * This function also stores a pointer to the kernel argument block in a TLS slot to be * picked up by the libc constructor. */ void __libc_init_tls(KernelArgumentBlock& args) { __libc_auxv = args.auxv; uintptr_t stack_top = (__get_sp() & ~(PAGE_SIZE - 1)) + PAGE_SIZE; size_t stack_size = get_main_thread_stack_size(); uintptr_t stack_bottom = stack_top - stack_size; static void* tls[BIONIC_TLS_SLOTS]; static pthread_internal_t thread; thread.tid = gettid(); thread.tls = tls; pthread_attr_init(&thread.attr); pthread_attr_setstack(&thread.attr, (void*) stack_bottom, stack_size); _init_thread(&thread, false); __init_tls(&thread); tls[TLS_SLOT_BIONIC_PREINIT] = &args; }
void __attribute__((naked)) isr_fault() { /* disable interrupts */ /* save registers */ unsigned int sp, lr, psr, usp; sp = __get_sp(); psr = __get_psr(); lr = __get_lr(); usp = __get_usp(); debug(MSG_ERROR, "\nFault type: %x <%08x>\n" " (%x=Usage fault, %x=Bus fault, %x=Memory management fault)", SCB_SHCSR & 0xfff, SCB_SHCSR, USAGE_FAULT, BUS_FAULT, MM_FAULT); debug(MSG_ERROR, "Fault source: "); busfault(); usagefault(); printk("\nKernel Space\n"); print_kernel_status((unsigned int *)sp, lr, psr); printk("\nUser Space\n"); print_user_status((unsigned int *)usp); printk("\nTask Status\n"); print_task_status(current); printk("\nCurrent Context\n"); print_context((unsigned int *)usp); printk("\nSCB_ICSR 0x%08x\n" "SCB_CFSR 0x%08x\n" "SCB_HFSR 0x%08x\n" "SCB_MMFAR 0x%08x\n" "SCB_BFAR 0x%08x\n", SCB_ICSR, SCB_CFSR, SCB_HFSR, SCB_MMFAR, SCB_BFAR); /* led for debugging */ #ifdef LED_DEBUG SET_PORT_CLOCK(ENABLE, PORTD); SET_PORT_PIN(PORTD, 2, PIN_OUTPUT_50MHZ); unsigned int j; while (1) { PUT_PORT(PORTD, GET_PORT(PORTD) ^ 4); for (i = 100; i; i--) { for (j = 10; j; j--) { __asm__ __volatile__( "nop \n\t" "nop \n\t" "nop \n\t" "nop \n\t" "nop \n\t" "nop \n\t" "nop \n\t" "nop \n\t" "nop \n\t" "nop \n\t" ::: "memory"); } } } #endif while (1); /* restore registers */ /* enable interrupts */ }