EXTERNAL void sysPerfEventEnable() { TRACE_PRINTF("%s: sysPerfEventEnable\n", Me); if (enabled) { if (prctl(PR_TASK_PERF_EVENTS_ENABLE)) { err(1, "error in prctl(PR_TASK_PERF_EVENTS_ENABLE)"); } } }
/** * Reads multiple bytes from file or socket. * Taken: file or socket descriptor * buffer to be filled * number of bytes requested * Returned: number of bytes delivered (-2: error, -1: socket would have blocked) */ EXTERNAL int sysReadBytes(int fd, char *buf, int cnt) { TRACE_PRINTF("%s: sysReadBytes %d %p %d\n", Me, fd, buf, cnt); while (1) { int rc = read(fd, buf, cnt); if (rc >= 0) return rc; int err = errno; if (err == EAGAIN) { TRACE_PRINTF("%s: read on %d would have blocked: needs retry\n", Me, fd); return -1; } else if (err != EINTR) { ERROR_PRINTF("%s: read error %d (%s) on %d\n", Me, err, strerror(err), fd); return -2; } else { // interrupted by signal; try again } } }
EXTERNAL void sysPerfEventRead(int id, long long *values) { TRACE_PRINTF("%s: sysPerfEventRead\n", Me); size_t expectedBytes = 3 * sizeof(long long); int ret = read(perf_event_fds[id], values, expectedBytes); if (ret < 0) { err(1, "error reading event: %s", strerror(errno)); } if (ret != expectedBytes) { errx(1, "read of perf event did not return 3 64-bit values"); } }
Hint fat16_getentry( fat16_t *fat, Huint cluster, Hushort *entry ) { Hint res; Huint sector; Huint offset; Hubyte buffer[512]; // Print out a trace message if configured TRACE_PRINTF( TRACE_FINE, FAT16_DEBUG, "entering\n" ); TRACE_PRINTF( TRACE_FATAL, fat == NULL, "NULL fat16 pointer\n" ); TRACE_PRINTF( TRACE_FATAL, entry == NULL, "NULL entry pointer\n" ); // Get the sector number and offset for the cluster sector = fat16_entry_sector( fat, cluster ); offset = fat16_entry_offset( fat, cluster ); // Read the sector containing the entry res = fat->block->read( fat->block, sector, 1, buffer ); if( res < 0 ) { TRACE_PRINTF( TRACE_ERR, FAT16_DEBUG, "error reading block device\n" ); TRACE_PRINTF( TRACE_FINE, FAT16_DEBUG, "exiting with error\n" ); return res; } // Store the entry *entry = ((Hushort*)buffer)[ offset ]; // Print out a trace message if configured TRACE_PRINTF( TRACE_FINE, FAT16_DEBUG, "exiting with success\n" ); // Return successfully return SUCCESS; }
/** \internal * \brief Voluntarily release the processor so that another thread * can be scheduled to run. * * \author Wesley Peck <*****@*****.**> * * This function is the system call routine which implements the * hthread_yield functionality for hthreads. The user space function * hthread_yield invokes this function to yield the processor. * * \return The return value is one of the following: * - SUCCESS : Currently there is no way for this function * to fail */ Hint _syscall_yield( void ) { Huint curr; Huint next; // Print out a trace message about this system call TRACE_PRINTF( TRACE_FINE, TRACE_SYSCALL, "SYSCALL: (OP=YIELD)\n" ); // Get the currently running thread curr = _current_thread(); // Get the next thread to run next = _yield_thread(); // Print out a trace message about this system call TRACE_PRINTF( TRACE_FINE, TRACE_SYSCALL, "SYSCALL DONE: (OP=YIELD)\n" ); // If they are not the same thread then switch to the new thread if( curr != next ) _switch_context( curr, next ); return SUCCESS; }
Hint fat16_direntry_free( fat16_direntry_t *entry ) { // Print out a trace message if configured TRACE_PRINTF( TRACE_FINE, FAT16_DEBUG, "entering\n" ); TRACE_PRINTF( TRACE_FATAL, entry == NULL, "NULL fat16 entry\n" ); if( entry->name[0] == 0xE5 ) { TRACE_PRINTF( TRACE_FINE, FAT16_DEBUG, "exiting with free\n" ); return 1; } else if( entry->name[0] == 0x00 ) { TRACE_PRINTF( TRACE_FINE, FAT16_DEBUG, "exiting with all free\n" ); return 2; } else { TRACE_PRINTF( TRACE_FINE, FAT16_DEBUG, "exiting with not free\n" ); return 0; } }
/** * Writes multiple bytes to file or socket. * Taken: file or socket descriptor * buffer to be written * number of bytes to write * Returned: number of bytes written (-2: error, -1: socket would have blocked, * -3 EPIPE error) */ EXTERNAL int sysWriteBytes(int fd, char *buf, int cnt) { TRACE_PRINTF("%s: sysWriteBytes %d %p %d\n", Me, fd, buf, cnt); while (1) { int rc = write(fd, buf, cnt); if (rc >= 0) return rc; int err = errno; if (err == EAGAIN) { TRACE_PRINTF("%s: write on %d would have blocked: needs retry\n", Me, fd); return -1; } else if (err == EINTR) { // interrupted by signal; try again } else if (err == EPIPE) { TRACE_PRINTF("%s: write on %d with nobody to read it\n", Me, fd); return -3; } else { ERROR_PRINTF("%s: write error %d (%s) on %d\n", Me, err, strerror( err ), fd); return -2; } } }
/** \internal * \brief Acquire a mutex lock. * * \author Wesley Peck <*****@*****.**> * * This function is used to acquire a lock for the given mutex. * * \param mutex The mutex to acquire the lock for. */ Hint _syscall_mutex_lock( hthread_mutex_t *mutex ) { Huint cur; Hint sta; // Print out a trace message about this system call TRACE_PRINTF( TRACE_FINE, TRACE_SYSCALL, "SYSCALL: (OP=LOCK) (MTX=%d)\n", (Huint)mutex->num ); cur = _current_thread(); sta = _mutex_acquire( cur, mutex->num ); // Print out a trace message about this system call TRACE_PRINTF( TRACE_FINE, TRACE_SYSCALL, "SYSCALL DONE: (OP=LOCK) (MTX=%d) (CUR=%u) (STA=%8.8X)\n", (Huint)mutex->num, cur, sta ); if( sta == HT_MUTEX_BLOCK ) { _run_sched( Htrue ); return SUCCESS; } if( sta == SUCCESS ) return SUCCESS; else return FAILURE; }
char* fat16_direntry_name( fat16_direntry_t *entry, char *buffer, Huint num ) { Hint i; Hint n; Hint lower; // Print out a trace message if configured TRACE_PRINTF( TRACE_FINE, FAT16_DEBUG, "entering\n" ); TRACE_PRINTF( TRACE_FATAL, entry == NULL, "NULL fat16 entry\n" ); TRACE_PRINTF( TRACE_FATAL, buffer == NULL, "NULL name buffer\n" ); // Return if there is no room if( num == 0 ) { TRACE_PRINTF( TRACE_ERR, FAT16_DEBUG, "empty name buffer given\n" ); TRACE_PRINTF( TRACE_FINE, FAT16_DEBUG, "exiting with success\n" ); return buffer; } // Reserve room for the terminating null num--; // Intialize the number of bytes copied n = 0; // Determine if we should name the name lower case or not lower = ((entry->reserved & 0x08) == 0x08); // Copy over the name, adding a period if neccessary for( i = 0; i < 11; i++ ) { if( entry->name[i] == ' ' || entry->name[i] == 0 ) { if( i < 8 ) { if( entry->name[8] == ' ' || entry->name[8] == 0 ) break; else i = 8; lower = ((entry->reserved & 0x10) == 0x10); } else { break; } } if( n < num && i == 8 ) buffer[n++] = '.'; if( n < num ) buffer[n++] = lower ? tolower(entry->name[i]) : entry->name[i]; } // Add terminating null to the name buffer[n++] = 0; // Print out a trace message if configured TRACE_PRINTF( TRACE_FINE, FAT16_DEBUG, "exiting with success\n" ); return buffer; }
/** \internal * \brief Wait on a condition variable. * * \author Wesley Peck <*****@*****.**> * * This function is used to try to acquire a lock for the given mutex. * * \param cond The condition variable to try to wait on. * \param mutex The mutex to try to used for the wait operation. */ Hint _syscall_cond_wait( hthread_cond_t *cond, hthread_mutex_t *mutex ) { Hint sta; Huint tid; // Print out a trace message about this system call TRACE_PRINTF( TRACE_FINE, TRACE_SYSCALL, "SYSCALL: (OP=WAIT) (CND=0x%8.8x) (MTX=0x%8.8x)\n", (Huint)cond, (Huint)mutex ); tid = _current_thread(); _condvar_wait( tid, cond->num ); sta = _syscall_mutex_unlock( mutex ); if( sta != SUCCESS ) return sta; _run_sched( Htrue ); sta = _syscall_mutex_lock( mutex ); if( sta != SUCCESS ) return sta; // Print out a trace message about this system call TRACE_PRINTF( TRACE_FINE, TRACE_SYSCALL, "SYSCALL DONE: (OP=WAIT) (CND=0x%8.8x) (MTX=0x%8.8x)\n", (Huint)cond, (Huint)mutex ); return SUCCESS; }
EXTERNAL void sysPerfEventCreate(int id, const char *eventName) { TRACE_PRINTF("%s: sysPerfEventCreate\n", Me); struct perf_event_attr *pe = (perf_event_attrs + id); int ret = pfm_get_perf_event_encoding(eventName, PFM_PLM3, pe, NULL, NULL); if (ret != PFM_SUCCESS) { errx(1, "error creating event %d '%s': %s\n", id, eventName, pfm_strerror(ret)); } pe->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING; pe->disabled = 1; pe->inherit = 1; perf_event_fds[id] = perf_event_open(pe, 0, -1, -1, 0); if (perf_event_fds[id] == -1) { err(1, "error in perf_event_open for event %d '%s'", id, eventName); } }
void Environment::run(RunningContext *context) { const Instruction &ins = m_ipos; m_context = context; if (!context) { m_running = false; } else if (!m_running) { clear_vstore(); TRACE_PRINTF(TRACE_VM, TRACE_INFO, "Entering running state with %p\n", context); m_running = true; SourcePos *last_pos = NULL; // used for debug output below. const Instruction *ipos; while (m_context && (ipos = m_context->next())) { size_t output = -1; size_t expected = -1; # define CHECK_STACK(in, out) TRACE_OUT(TRACE_VM, TRACE_SPAM) {\ assert(m_context->stack_count() >= (size_t)(in)); \ if ((out) != -1) { assert((long)(expected = m_context->stack_count() - (size_t)(in) + (size_t)(out)) >= 0); } \ tprintf("Stack info: before(%d), in(%d), out(%d), expected(%d)\n", (int)m_context->stack_count(), (int)(in), (int)(out), (int)expected); \ output = (out); \ } m_ipos = *ipos; TRACE_DO(TRACE_VM, TRACE_INFO) { SourcePos &pos = m_context->m_instructions->source_pos(ipos); if (!last_pos || *last_pos != pos) tprintf("Source Position: %s:%d:%d (%s)\n", pos.file.c_str(), (int)pos.line_num, (int)pos.column, pos.annotation.c_str()); last_pos = &pos; } TRACE_OUT(TRACE_VM, TRACE_SPAM) { tprintf("Instruction: %s@%d\n", inspect(ins).c_str(), (int)(ipos - &*m_context->instructions().begin()) ); tprintf("Stack: %d deep", (int)m_context->stack_count()); const Value *it; for (it = m_context->stack_begin(); it != m_context->stack_pos(); it++) { tprintf("\n %s", inspect(*it).c_str()); } tprintf(" <--\n"); }
void write_ptr(void *obj, tField &field, const tVal &val) { assert(sizeof(val) == sizeof(uintptr_t)); if ((!obj || generation_of(obj) > m_generation) && is_generation(val, m_generation)) { // TODO: What to do when this happens? Maybe it should be a deque anyways. if (m_free < sizeof(Remembered)) throw std::runtime_error("No free space for remembered set! PANIC!"); TRACE_PRINTF(TRACE_GC, TRACE_DEBUG, "Write barrier (%u), adding: %p(%s) <- %p(%s)\n", m_generation, &field, obj && is_generation(&obj, m_generation)? "yes":"no", *(void**)&val, is_generation(val, m_generation)? "yes":"no"); m_free -= sizeof(Remembered); Remembered *r = --m_remembered_set; VALGRIND_MEMPOOL_ALLOC(m_data, r, sizeof(Remembered)); r->in_object = obj; r->location = (uintptr_t*)&field; r->val = *(uintptr_t*)&val; } }
/** * Writes one byte to file. * Taken: file descriptor * data to write * Returned: -2 operation would block, -1: error, 0: success */ EXTERNAL int sysWriteByte(int fd, int data) { char ch = data; TRACE_PRINTF("%s: sysWriteByte %d %c\n", Me, fd, ch); while (1) { int rc = write(fd, &ch, 1); if (rc == 1) { return 0; // success } else if (errno == EAGAIN) { return -2; // operation would block } else if (errno == EINTR) { // interrupted by signal; try again } else { ERROR_PRINTF("%s: writeByte, fd=%d, write returned error %d (%s)\n", Me, fd, errno, strerror(errno)); return -1; // some kind of error } } }
inline void *raw_alloc(size_t object_size, ValueType type, bool pinned) { size_t data_size = sizeof(Data) + object_size; if (!pinned && data_size < m_free) { Data *data = (Data*)m_next_pos; VALGRIND_MEMPOOL_ALLOC(m_data, m_next_pos, data_size); m_next_pos += data_size; m_free -= data_size; m_data_blocks++; data->init(object_size, type, m_generation); TRACE_PRINTF(TRACE_ALLOC, TRACE_SPAM, "Nursery%u Alloc %u type %x ... got %p ... alloc return %p\n", m_generation, (unsigned)object_size, type, data, data->m_data); return data->m_data; } else { return m_next->raw_alloc(object_size, type, pinned); } }
Hint fat16_create( fat16_t *fat, fat16_prt_t *part, block_t *block ) { Hint res; fat16_bts_t boot; // Print out a trace message if configured TRACE_PRINTF( TRACE_FINE, FAT16_DEBUG, "entering\n" ); TRACE_PRINTF( TRACE_FATAL, fat == NULL, "NULL fat16 pointer\n" ); TRACE_PRINTF( TRACE_FATAL, part == NULL, "NULL partition pointer\n" ); TRACE_PRINTF( TRACE_FATAL, block == NULL, "NULL block device\n" ); // Store the device used for physical access fat->block = block; // Store important information from the partition fat->first_sector = part->offset; fat->last_sector = part->offset + part->size; fat->boot_sector = fat->first_sector; // Read the boot sector from the disk res = fat16_boots_read( fat->block, &boot, fat->boot_sector ); if( res < 0 ) { TRACE_PRINTF( TRACE_ERR, FAT16_DEBUG, "error reading boot sector\n" ); TRACE_PRINTF( TRACE_FINE, FAT16_DEBUG, "exiting with error\n" ); return res; } // Store important information from the boot sector fat->sectors = boot.ssectors != 0 ? boot.ssectors : boot.sectors; fat->bt_sector = boot.bytes_per_sector; fat->fat_sector = fat->first_sector + boot.reserved_sectors; fat->fat_size = boot.sectors_per_fat; fat->root_sector = fat->fat_sector + (boot.fats * boot.sectors_per_fat); fat->root_size = ((boot.max_root * 32) + (fat->bt_sector-1)) / fat->bt_sector; fat->data_sector = fat->root_sector + fat->root_size; fat->data_size = fat->sectors-fat->fat_sector-fat->root_size-fat->first_sector; fat->cl_sectors = boot.sectors_per_cluster; // Print out a trace message if configured TRACE_PRINTF( TRACE_FINE, FAT16_DEBUG, "exiting with success\n" ); // Return successfully return SUCCESS; }
EXTERNAL void sysPerfEventInit(int numEvents) { int i; TRACE_PRINTF("%s: sysPerfEventInit\n", Me); int ret = pfm_initialize(); if (ret != PFM_SUCCESS) { errx(1, "error in pfm_initialize: %s", pfm_strerror(ret)); } perf_event_fds = (int*)checkCalloc(numEvents, sizeof(int)); if (!perf_event_fds) { errx(1, "error allocating perf_event_fds"); } perf_event_attrs = (struct perf_event_attr *)checkCalloc(numEvents, sizeof(struct perf_event_attr)); if (!perf_event_attrs) { errx(1, "error allocating perf_event_attrs"); } for(i = 0; i < numEvents; i++) { perf_event_attrs[i].size = sizeof(struct perf_event_attr); } enabled = 1; }
/** * Write one byte to file. * * @param fd file descriptor * @param data data to write * @return -2 operation would block, -1: error, 0: success */ EXTERNAL int sysWriteByte(int fd, int data) { SYS_START(); char ch = data; TRACE_PRINTF("%s: sysWriteByte %d %c\n", Me, fd, ch); #ifdef RVM_FOR_HARMONY return hyfile_write(fd, &ch, 1); #else while(1) { int rc = write(fd, &ch, 1); if (rc == 1) { return 0; // success } else if (errno == EAGAIN) { return -2; // operation would block } else if (errno == EINTR) { } else { ERROR_PRINTF("%s: writeByte, fd=%d, write returned error %d (%s)\n", Me, fd, errno, strerror(errno)); return -1; // some kind of error } } #endif // RVM_FOR_HARMONY }
/** * Reads jfloat var arg * * Taken: va_list [in,out] var arg list update to next entry after read * Returned: argument */ EXTERNAL jfloat sysVaArgJfloat(va_list *ap) { jfloat result = (jfloat)va_arg(*ap, jdouble); TRACE_PRINTF("%s: sysVaArgJfloat %f\n", Me, result); return result; }
/** * Ends use of va_list */ EXTERNAL void sysVaEnd(va_list *ap) { TRACE_PRINTF("%s: sysVaEnd\n", Me); va_end(*ap); sysFree(ap); }
/** * Parse command line arguments to find those arguments that * 1) affect the starting of the VM, * 2) can be handled without starting the VM, or * 3) contain quotes * then call createVM(). */ int main(int argc, const char **argv) { int vbufret, j, ret; JavaVMInitArgs initArgs; JavaVM *mainJavaVM; JNIEnv *mainJNIEnv; /* Make standard streams unbuffered so that we can use them for low level-debugging */ vbufret = setvbuf(stdout, NULL, _IONBF, 0); if (vbufret != 0) { printf("Error making stdout unbuffered: %d\n", vbufret); } vbufret = setvbuf(stderr, NULL, _IONBF, 0); if (vbufret != 0) { printf("Error making stderr unbuffered: %d\n", vbufret); } SysErrorFile = stderr; SysTraceFile = stdout; Me = strrchr(*argv, '/'); if (Me == NULL) { Me = "RVM"; } else { Me++; } ++argv, --argc; initialHeapSize = heap_default_initial_size; maximumHeapSize = heap_default_maximum_size; // Determine page size information early because // it's needed to parse command line options pageSize = (Extent) determinePageSize(); if (pageSize <= 0) { ERROR_PRINTF("RunBootImage.main(): invalid page size %u", pageSize); exit(EXIT_STATUS_IMPOSSIBLE_LIBRARY_FUNCTION_ERROR); } /* * Debugging: print out command line arguments. */ if (TRACE) { TRACE_PRINTF("RunBootImage.main(): process %d command line arguments\n",argc); for (j = 0; j < argc; j++) { TRACE_PRINTF("\targv[%d] is \"%s\"\n",j, argv[j]); } } /* Initialize JavaArgc, JavaArgs and initArg */ initArgs.version = JNI_VERSION_1_4; initArgs.ignoreUnrecognized = JNI_TRUE; JavaArgs = (char **)processCommandLineArguments(&initArgs, argv, argc); if (TRACE) { TRACE_PRINTF("RunBootImage.main(): after processCommandLineArguments: %d command line arguments\n", JavaArgc); for (j = 0; j < JavaArgc; j++) { TRACE_PRINTF("\tJavaArgs[%d] is \"%s\"\n", j, JavaArgs[j]); } } /* Verify heap sizes for sanity. */ if (initialHeapSize == heap_default_initial_size && maximumHeapSize != heap_default_maximum_size && initialHeapSize > maximumHeapSize) { initialHeapSize = maximumHeapSize; } if (maximumHeapSize == heap_default_maximum_size && initialHeapSize != heap_default_initial_size && initialHeapSize > maximumHeapSize) { maximumHeapSize = initialHeapSize; } if (maximumHeapSize < initialHeapSize) { CONSOLE_PRINTF( "%s: maximum heap size %lu MiB is less than initial heap size %lu MiB\n", Me, (unsigned long) maximumHeapSize/(1024*1024), (unsigned long) initialHeapSize/(1024*1024)); return EXIT_STATUS_BOGUS_COMMAND_LINE_ARG; } TRACE_PRINTF("\nRunBootImage.main(): VM variable settings\n"); TRACE_PRINTF("initialHeapSize %lu\nmaxHeapSize %lu\n" "bootCodeFileName \"%s\"\nbootDataFileName \"%s\"\n" "bootRmapFileName \"%s\"\n" "verbose %d\n", (unsigned long) initialHeapSize, (unsigned long) maximumHeapSize, bootCodeFilename, bootDataFilename, bootRMapFilename, verbose); if (!bootCodeFilename) { CONSOLE_PRINTF( "%s: please specify name of boot image code file using \"-X:ic=<filename>\"\n", Me); return EXIT_STATUS_BOGUS_COMMAND_LINE_ARG; } if (!bootDataFilename) { CONSOLE_PRINTF( "%s: please specify name of boot image data file using \"-X:id=<filename>\"\n", Me); return EXIT_STATUS_BOGUS_COMMAND_LINE_ARG; } if (!bootRMapFilename) { CONSOLE_PRINTF( "%s: please specify name of boot image ref map file using \"-X:ir=<filename>\"\n", Me); return EXIT_STATUS_BOGUS_COMMAND_LINE_ARG; } ret = JNI_CreateJavaVM(&mainJavaVM, &mainJNIEnv, &initArgs); if (ret < 0) { ERROR_PRINTF("%s: Could not create the virtual machine; goodbye\n", Me); exit(EXIT_STATUS_MISC_TROUBLE); } return 0; }
/** \internal * \brief The Hybrid Threads initialization function. * * This function is the Hybrid Threads initialization function. This function * must be called before any other HThread's functionality is used. */ void hthread_init( void ) { int ret, i; hthread_t main_thread; hthread_t idle_thread; hthread_attr_t attrs; Huint status; #ifdef HTHREADS_SMP int cpuid; if(_get_procid() == 0) { /* Default all stack values to NULL */ for( i = 0; i < MAX_THREADS; i++ ) threads[ i ].stack = NULL; /* Initialize the thread manager */ _init_thread_manager(); // Have to acknowledge the access interrupt generated because // spinlock and semaphore cores cause a failure // Hardcoded...FIXME intr_ack( 0x41200000, ACCESS_INTR_MASK ); intr_ack( 0x41210000, ACCESS_INTR_MASK ); // Must call this function again because we just reset the TM after // already reading CPUID = 0, therefore the next call to _init_cpuid() // will also return zero, giving two cpu's the id of zero _init_cpuid(); // Setup the attributes for the idle thread attrs.detached = Htrue; attrs.stack_size = HT_IDLE_STACK_SIZE; attrs.hardware = Hfalse; attrs.stack_addr = (void*)NULL; attrs.sched_param = 0x0000007F; // Worst possible priority // Create the idle thread _create_system_thread( &idle_thread, &attrs, _idle_thread, NULL ); TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "HThread Init: (IDLE ID(PPC_%d)=%u)\n", _get_procid(), idle_thread ); // Tell the hardware what the idle thread is _set_idle_thread( idle_thread, _get_procid() ); //hthread_spin_lock(&(_sysc_lock)); // Enable PPC specific interrupts //_arch_enable_intr(); // Initialize the Architecture Specific Code TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "Initializing Architecture...\n" ); //_init_arch_specific( idle_thread ); //_init_arch_specific(); // Need to acquire lock here because bootstrap releases lock while(!_get_syscall_lock()); _restore_context( 0 , idle_thread ); } else { // Setup the attributes for the main thread attrs.detached = Htrue; // The Main Thread is Detached attrs.stack_size = HT_MAIN_STACK_SIZE; // Stack Size for Main Thread attrs.hardware = Hfalse; // The Main Thread is not Hardware attrs.stack_addr = (void*)0xFFFFFFFF; // The Main Thread Already Has a Stack attrs.sched_param = HT_DEFAULT_PRI; // Middle of the Road Priority // Create the main thread _create_system_thread( &main_thread, &attrs, NULL, NULL ); TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "HThread Init: (MAIN ID(PPC_%d)=%u)\n", _get_procid(), main_thread ); // Prevent the system from attempting to deallocate the main stack threads[ main_thread ].stack = NULL; // Add the main thread onto the ready-to-run queue status = _add_thread( main_thread ); // Set the next thread to be the current thread. This should place // the main thread into the current thread register. status = _next_thread(); // The main thread is not a new thread threads[ main_thread ].newthread = Hfalse; // Setup the attributes for the idle thread attrs.detached = Htrue; attrs.stack_size = HT_IDLE_STACK_SIZE; attrs.hardware = Hfalse; attrs.stack_addr = (void*)NULL; attrs.sched_param = 0x0000007F; // Worst possible priority // Create the idle thread _create_system_thread( &idle_thread, &attrs, _idle_thread, NULL ); TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "HThread Init: (IDLE ID(PPC_%d)=%u)\n", _get_procid(), idle_thread ); // Tell the hardware what the idle thread is _set_idle_thread( idle_thread, _get_procid() ); // Enable PPC specific interrupts //_arch_enable_intr(); // Initialize the Architecture Specific Code TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "Initializing Architecture...\n" ); //_init_arch_specific( main_thread ); //_init_arch_specific(); // Enter into user mode //_arch_enter_user(); _enable_preemption(); } #else // Initialize all of the thread stacks to NULL TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "Initializing HThreads System...\n" ); for( i = 0; i < MAX_THREADS; i++ ) threads[ i ].stack = NULL; // Initialize the Thread Manager TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "Initializing Thread Manager...\n" ); _init_thread_manager(); // Setup the attributes for the main thread attrs.detached = Htrue; // Main thread is detached attrs.stack_size = HT_MAIN_STACK_SIZE; // Stack size for main thread attrs.hardware = Hfalse; // Main thread is not hardware attrs.stack_addr = (void*)0xFFFFFFFF; // Main thread has a stack attrs.sched_param = HT_DEFAULT_PRI; // Middle of the road priority // Create the main thread ret = _create_system_thread( &main_thread, &attrs, NULL, NULL ); TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "HThread Init: (MAIN ID=%u)\n", main_thread ); if( ret != SUCCESS ) { TRACE_PRINTF(TRACE_FATAL, TRACE_INIT, "HThread Init: create main thread failed\n" ); while(1); } // Initialize the Architecture Specific Code TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "Initializing Architecture...\n" ); //_init_arch_specific(); // Prevent the system from attempting to deallocate the main stack threads[ main_thread ].stack = NULL; // Add the main thread onto the ready-to-run queue status = _add_thread( main_thread ); // Set the next thread to be the current thread. This should place // the main thread into the current thread register. status = _next_thread(); // Setup the attributes for the idle thread attrs.detached = Htrue; attrs.stack_addr = (void*)NULL; attrs.stack_size = HT_IDLE_STACK_SIZE; // Create the idle thread ret = _create_system_thread( &idle_thread, &attrs, _idle_thread, NULL ); TRACE_PRINTF( TRACE_INFO, TRACE_INIT, "HThread Init: (IDLE ID=%u)\n", idle_thread ); if( ret != SUCCESS ) { TRACE_PRINTF(TRACE_FATAL, TRACE_INIT, "HThread Init: create idle thread failed\n" ); while(1); } // Tell the hardware what the idle thread is // FIXME - The CPUID is hardcoded, fix the manager/hardware.h file! _set_idle_thread( idle_thread , 0); // The main thread is not a new thread threads[ main_thread ].newthread = Hfalse; // Enter into user mode //_arch_enable_intr(); //_arch_enter_user(); #endif }
/** * Reads jlong var arg * * Taken: va_list [in,out] var arg list update to next entry after read * Returned: argument */ EXTERNAL jlong sysVaArgJlong(va_list *ap) { jlong result = va_arg(*ap, jlong); TRACE_PRINTF("%s: sysVaArgJlong %lld\n", Me, (long long int)result); return result; }
/** * Reads jobject var arg * * Taken: va_list [in,out] var arg list update to next entry after read * Returned: argument */ EXTERNAL jobject sysVaArgJobject(va_list *ap) { jobject result = va_arg(*ap, jobject); TRACE_PRINTF("%s: sysVaArgJobject %p\n", Me, (void *)result); return result; }
/** * Reads jint var arg * * Taken: va_list [in,out] var arg list update to next entry after read * Returned: argument */ EXTERNAL jint sysVaArgJint(va_list *ap) { jint result = va_arg(*ap, jint); TRACE_PRINTF("%s: sysVaArgJint %d\n", Me, result); return result; }
/** * Reads jchar var arg * * Taken: va_list [in,out] var arg list update to next entry after read * Returned: argument */ EXTERNAL jchar sysVaArgJchar(va_list *ap) { jchar result = (jchar)va_arg(*ap, jint); TRACE_PRINTF("%s: sysVaArgJchar %d\n", Me, result); return result; }
/** * Reads jbyte var arg * * Taken: va_list [in,out] var arg list update to next entry after read * Returned: argument */ EXTERNAL jbyte sysVaArgJbyte(va_list *ap) { jbyte result = (jbyte)va_arg(*ap, jint); TRACE_PRINTF("%s: sysVaArgJbyte %d\n", Me, result); return result; }
/** * Reads jboolean var arg * * Taken: va_list [in,out] var arg list update to next entry after read * Returned: argument */ EXTERNAL jboolean sysVaArgJboolean(va_list *ap) { jboolean result = (jboolean)va_arg(*ap, jint); TRACE_PRINTF("%s: sysVaArgJboolean %d\n", Me, result); return result; }
/** * Reads jshort var arg * * Taken: va_list [in,out] var arg list update to next entry after read * Returned: argument */ EXTERNAL jshort sysVaArgJshort(va_list *ap) { jshort result = (jshort)va_arg(*ap, jint); TRACE_PRINTF("%s: sysVaArgJshort %d\n", Me, result); return result; }
/** * Reads jdouble var arg * * Taken: va_list [in,out] var arg list update to next entry after read * Returned: argument */ EXTERNAL jdouble sysVaArgJdouble(va_list *ap) { jdouble result = va_arg(*ap, jdouble); TRACE_PRINTF("%s: sysVaArgJdouble %f\n", Me, result); return result; }