You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

context.c 2.9KB

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