|
|
1.1 ! root 1: /* ! 2: * context switching ! 3: * 2003-10 by SONE Takeshi ! 4: */ ! 5: ! 6: #include "config.h" ! 7: #include "kernel/kernel.h" ! 8: #include "segment.h" ! 9: #include "context.h" ! 10: ! 11: #define MAIN_STACK_SIZE 16384 ! 12: #define IMAGE_STACK_SIZE 4096 ! 13: ! 14: #define debug printk ! 15: ! 16: static void start_main(void); /* forward decl. */ ! 17: void __exit_context(void); /* assembly routine */ ! 18: ! 19: /* ! 20: * Main context structure ! 21: * It is placed at the bottom of our stack, and loaded by assembly routine ! 22: * to start us up. ! 23: */ ! 24: struct context main_ctx __attribute__((section (".initctx"))) = { ! 25: .gdt_base = (uint64_t) gdt, ! 26: .gdt_limit = GDT_LIMIT, ! 27: .cs = FLAT_CS, ! 28: .ds = FLAT_DS, ! 29: .es = FLAT_DS, ! 30: .fs = FLAT_DS, ! 31: .gs = FLAT_DS, ! 32: .ss = FLAT_DS, ! 33: .esp = (uint32_t) ESP_LOC(&main_ctx), ! 34: .eip = (uint32_t) start_main, ! 35: .return_addr = (uint32_t) __exit_context, ! 36: }; ! 37: ! 38: /* This is used by assembly routine to load/store the context which ! 39: * it is to switch/switched. */ ! 40: struct context *__context = &main_ctx; ! 41: ! 42: /* Stack for loaded ELF image */ ! 43: static uint8_t image_stack[IMAGE_STACK_SIZE]; ! 44: ! 45: /* Pointer to startup context (physical address) */ ! 46: unsigned long __boot_ctx; ! 47: ! 48: /* ! 49: * Main starter ! 50: * This is the C function that runs first. ! 51: */ ! 52: static void start_main(void) ! 53: { ! 54: int retval; ! 55: extern int openbios(void); ! 56: ! 57: /* Save startup context, so we can refer to it later. ! 58: * We have to keep it in physical address since we will relocate. */ ! 59: __boot_ctx = virt_to_phys(__context); ! 60: ! 61: /* Start the real fun */ ! 62: retval = openbios(); ! 63: ! 64: /* Pass return value to startup context. Bootloader may see it. */ ! 65: boot_ctx->eax = retval; ! 66: ! 67: /* Returning from here should jump to __exit_context */ ! 68: __context = boot_ctx; ! 69: } ! 70: ! 71: /* Setup a new context using the given stack. ! 72: */ ! 73: struct context * ! 74: init_context(uint8_t *stack, uint32_t stack_size, int num_params) ! 75: { ! 76: struct context *ctx; ! 77: ! 78: ctx = (struct context *) ! 79: (stack + stack_size - (sizeof(*ctx) + num_params*sizeof(uint32_t))); ! 80: memset(ctx, 0, sizeof(*ctx)); ! 81: ! 82: /* Fill in reasonable default for flat memory model */ ! 83: ctx->gdt_base = virt_to_phys(gdt); ! 84: ctx->gdt_limit = GDT_LIMIT; ! 85: ctx->cs = FLAT_CS; ! 86: ctx->ds = FLAT_DS; ! 87: ctx->es = FLAT_DS; ! 88: ctx->fs = FLAT_DS; ! 89: ctx->gs = FLAT_DS; ! 90: ctx->ss = FLAT_DS; ! 91: ctx->esp = virt_to_phys(ESP_LOC(ctx)); ! 92: ctx->return_addr = virt_to_phys(__exit_context); ! 93: ! 94: return ctx; ! 95: } ! 96: ! 97: /* Switch to another context. */ ! 98: struct context *switch_to(struct context *ctx) ! 99: { ! 100: struct context *save, *ret; ! 101: ! 102: debug("switching to new context:\n"); ! 103: save = __context; ! 104: __context = ctx; ! 105: asm ("pushl %cs; call __switch_context"); ! 106: ret = __context; ! 107: __context = save; ! 108: return ret; ! 109: } ! 110: ! 111: /* Start ELF Boot image */ ! 112: uint32_t start_elf(uint32_t entry_point, uint32_t param) ! 113: { ! 114: struct context *ctx; ! 115: ! 116: ctx = init_context(image_stack, sizeof image_stack, 1); ! 117: ctx->eip = entry_point; ! 118: ctx->param[0] = param; ! 119: ctx->eax = 0xe1fb007; ! 120: ctx->ebx = param; ! 121: ! 122: ctx = switch_to(ctx); ! 123: return ctx->eax; ! 124: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.