Exemplo n.º 1
0
void kernel_createtask(int* returnPtr, int priority, int code, int notUsed) {
  addr mem = allocate_user_memory();
  if (mem == NULL) {
    *returnPtr = -2;
  }
  volatile TaskDescriptor* td = &tds[tid_counter];
  td->id = tid_counter++;
	td->state = READY;
	td->priority = priority;
	kernel_mytid((int*)&(td->parent_id), 0, 0, 0);
  td->next = (TaskDescriptor*)NULL;
  td->sendQ = (TaskDescriptor*)NULL;
  td->sp = (int*)(mem + STACK_SIZE) - 16; // Bottom of stack are fake register values
  td->sp[13] = code; // PC_USR
  td->sp[14] = 0x50; // spsr, enabled IRQ interrupt, disable FIQ
  td->sp[15] = (int) Exit; // LR_USR

	scheduler_append(td);
	*returnPtr = td->id;
}
Exemplo n.º 2
0
/*
 * allocate_memory()
 *
 * This function attempts to locate sections using
 * a best-fit algorithm. The term "best-fit" implies
 * that the smallest suitable free block will be used
 * for each section. This approach makes efficient use
 * of the free block list and reduces fragmentation.
 *
 * Called by: ldemul_after_allocation()
 *
 * Calls:     allocate_program_memory()
 *            allocate_data_memory()
 *            bfd_map_over_sections()
 *
 * If any of the sub-processes fail, report it
 * and continue. This helps to suppress misleading
 * messages, and follows the general philosophy
 * of doing as much work as we can, despite the
 * occurrence of fatal errors.
 */
static void
allocate_memory() {
  int result;
  lang_output_section_statement_type **last_os;

#define ERR_STR " Link Error: Could not allocate "

  /* save the last output section statement
     after sequential allocation */
  last_os = (lang_output_section_statement_type **) statement_list.tail;

  /*
   * Build an ordered list of output sections
   * that were placed by sequential allocator.
   * It will help identify any gaps between
   * output sections that are available.
   */
  pic32_init_section_list (&pic32_section_list);

  bfd_map_over_sections (link_info.output_bfd, &pic32_build_section_list, NULL);
  bfd_map_over_sections (link_info.output_bfd, &pic32_build_section_list_vma, NULL);

  if (pic32_debug) {
    pic32_print_section_list(unassigned_sections, "unassigned");
    pic32_print_section_list(memory_region_list, "memory region");
  }

  result = allocate_data_memory();
  if (result != 0)
    einfo(_("%F%sdata memory\n"), ERR_STR );

  result = allocate_program_memory();
  if (result != 0)
    einfo(_("%F%sprogram memory\n"), ERR_STR );
#if 0
  if (has_user_defined_memory) {
    result = allocate_user_memory();
    if (result != 0)
      einfo(_("%F%suser-defined memory region\n"), ERR_STR );
  }
#endif
  /* allocate the heap, if required */

  /* allocate the stack, unless the user has defined one */

  /* free the output section list */
  pic32_free_section_list(&pic32_section_list);

  /*
   * Scan over the output section statements
   * and merge any contiguous sections
   * with the same name, unless the
   * --unique option tells us not to.
   *
   * We start where the sequential allocator
   * finished, so that any merges are well understood.
   * For example, all of the best-fit output sections
   * contain a single input section.
   */
  {
    lang_statement_union_type *os, *next;
    asection *sec, *next_sec;
    unsigned int len, match, merge_sec = 0;
    bfd_vma sec_len, next_len = 0, merge_len = 0;
    char *p,*p2;

    if (pic32_debug)
      printf("\nScanning the output statements\n");

    for (os = (lang_statement_union_type *) *last_os;
         os != (lang_statement_union_type *) NULL;
         os = next) {

      /* clear the accumulator, if we didn't just merge */
      if (!merge_sec) merge_len = 0;

      merge_sec = 0;
      next = os->header.next;
      if (os->header.type == lang_output_section_statement_enum) {

        if (os->output_section_statement.bfd_section == NULL)
          /* --gc-sections has discarded this section */
          continue;

        sec = os->output_section_statement.bfd_section;
        if (os->output_section_statement.children.head                                      ->input_section.section->rawsize)
          sec_len = os->output_section_statement.children.head
                    ->input_section.section->rawsize;
        else
          sec_len = os->output_section_statement.children.head
                    ->input_section.section->size;

        if (!sec || !sec->name) continue;

        if (next && (next->header.type == lang_output_section_statement_enum)) {
          next_sec = next->output_section_statement.bfd_section;
	  if (next->output_section_statement.children.head) {
            if (next->output_section_statement.children.head->
                         input_section.section->rawsize)
              next_len = next->output_section_statement.children.head->
                         input_section.section->rawsize;
            else
              next_len = next->output_section_statement.children.head->
                         input_section.section->size;
          }

          if (!next_sec || !next_sec->name) continue;

          if (next->output_section_statement.children.head->
                input_section.section->size == 0) continue;

          /* if section address and len don't match, continue */
          if ((sec->lma + sec_len + merge_len) != next_sec->lma) continue;

          p = strchr(sec->name, '%');
          p2 = strchr(next_sec->name, '%');
          if (p && p2) {
            len = p - sec->name;
            if (len != (unsigned) (p2 - next_sec->name))
              continue;
            match = (strncmp(sec->name, next_sec->name, len) == 0);
          } else
            match = (strcmp(sec->name, next_sec->name) == 0);

          if (match && !config.unique_orphan_sections &&
              !pic32_unique_section(sec->name) &&
              (pic32_attribute_map(sec) == pic32_attribute_map(next_sec))) {

            if (pic32_debug) {
              printf("  Merging output sections %s and %s\n",
                      sec->name, next_sec->name);
              printf("    %s: addr = %lx, len = %lx\n",
                     sec->name, sec->lma, sec_len + merge_len);
              printf("    %s: addr = %lx, len = %lx\n",
                     next_sec->name, next_sec->lma, next_len);
            }

            merge_sec = 1; /* set a flag to indicate we're merging */
            merge_len += next_len;
            next->output_section_statement.children.head->
              input_section.section->output_section = NULL;

            lang_add_section (&os->output_section_statement.children,
                              next->output_section_statement.children.head
                              ->input_section.section,
                              &os->output_section_statement);

            /* remove the merged section from output_bfd */
            remove_section_from_bfd(link_info.output_bfd, next_sec);
          }
        }
      }

      if (merge_sec) {
        os->header.next = next->header.next;  /* unlink the merged statement */
        next = os;                            /* try to merge another one */
      }
    }
  }

} /* allocate_memory() */