static int32_t Coginit__(int cogid, void *stacktop, void *func, int32_t arg1, int32_t arg2, int32_t arg3, int32_t arg4) { void *tmp = __builtin_alloca(1984); unsigned int *sp = (unsigned int *)stacktop; static int32_t cogargs__[5]; int r; cogargs__[0] = (int32_t) func; cogargs__[1] = arg1; cogargs__[2] = arg2; cogargs__[3] = arg3; cogargs__[4] = arg4; _clone_cog(tmp); *--sp = 0; *--sp = (unsigned int)cogargs__; *--sp = (unsigned int)Cogstub__; r = coginit(cogid, tmp, sp); return r; }
int main(void) { uint8_t *buffer = (uint8_t *)(((uint32_t)padded_buffer + 15) & ~15); SdLoaderInfo *info = (SdLoaderInfo *)_load_start_coguser0; uint32_t load_address, index_width, offset_width, addr, count; uint32_t tags_size, cache_size, cache_lines, cache_tags, mboxes, *sp; VolumeInfo vinfo; FileInfo finfo; PexeFileHdr *hdr; int sd_id, i; uint8_t *p; // determine the cache size and setup cache variables index_width = info->cache_geometry >> 8; offset_width = info->cache_geometry & 0xff; tags_size = (1 << index_width) * 4; cache_size = 1 << (index_width + offset_width); cache_lines = HUB_SIZE - cache_size; cache_tags = cache_lines - tags_size; mboxes = cache_tags - sizeof(xmem_mbox_t) * 8 - 4; xmem_mbox = (xmem_mbox_t *)mboxes; // load the external memory driver DPRINTF("Loading external memory driver\n"); memset((void *)mboxes, 0, sizeof(xmem_mbox_t) * 8 + 4); xmem_mbox[8].hubaddr = XMEM_END; cognew(_load_start_coguser1, mboxes); DPRINTF("Loading SD driver\n"); sd_mbox = (uint32_t *)mboxes - 2; sd_mbox[0] = 0xffffffff; if ((sd_id = cognew(_load_start_coguser2, sd_mbox)) < 0) { DPRINTF("Error loading SD driver\n"); return 1; } while (sd_mbox[0]) ; DPRINTF("Initializing SD card\n"); if (SD_Init(sd_mbox, 5) != 0) { DPRINTF("SD card initialization failed\n"); return 1; } DPRINTF("Mounting filesystem\n"); if (MountFS(buffer, &vinfo) != 0) { DPRINTF("MountFS failed\n"); return 1; } // open the .pex file DPRINTF("Opening 'autorun.pex'\n"); if (FindFile(buffer, &vinfo, FILENAME, &finfo) != 0) { DPRINTF("FindFile '%s' failed\n", FILENAME); return 1; } // read the file header DPRINTF("Reading PEX file header\n"); if (GetNextFileSector(&finfo, kernel_image, &count) != 0 || count < PEXE_HDR_SIZE) { DPRINTF("Error reading PEX file header\n"); return 1; } // verify the header DPRINTF("Verifying PEX file header\n"); hdr = (PexeFileHdr *)kernel_image; if (strncmp(hdr->tag, PEXE_TAG, sizeof(hdr->tag)) != 0 || hdr->version != PEXE_VERSION) { DPRINTF("Bad PEX file header\n"); return 1; } load_address = hdr->loadAddress; // move past the header memmove(kernel_image, (uint8_t *)kernel_image + PEXE_HDR_SIZE, SECTOR_SIZE - PEXE_HDR_SIZE); p = (uint8_t *)kernel_image + SECTOR_SIZE - PEXE_HDR_SIZE; // read the .kernel cog image DPRINTF("Reading kernel image\n"); for (i = 1; i < 4; ++i) { if (GetNextFileSector(&finfo, p, &count) != 0 || count < SECTOR_SIZE) return 1; p += SECTOR_SIZE; } // load the image DPRINTF("Loading image at 0x%08x\n", load_address); addr = load_address; while (GetNextFileSector(&finfo, buffer, &count) == 0) { write_block(addr, buffer, XMEM_SIZE_512); addr += SECTOR_SIZE; } // stop the sd driver DPRINTF("Stopping SD driver\n"); cogstop(sd_id); // setup the stack // at start stack contains xmem_mbox, cache_tags, cache_lines, cache_geometry, pc sp = (uint32_t *)mboxes; *--sp = load_address; *--sp = info->cache_geometry; *--sp = cache_lines; *--sp = cache_tags; *--sp = mboxes; // start the xmm kernel boot code DPRINTF("Starting kernel\n"); coginit(cogid(), kernel_image, sp); // should never reach this return 0; }