PageRenderTime 29ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/usr/init/setup.c

https://bitbucket.org/matthias_lei/advanced-operating-systems-project
C | 263 lines | 173 code | 52 blank | 38 comment | 27 complexity | 13c064c3815a2bc2c6592731395e9b48 MD5 | raw file
Possible License(s): BSD-2-Clause, BSD-3-Clause
  1. /**
  2. * Group C
  3. */
  4. #include "setup.h"
  5. #include "mem_alloc.h"
  6. #include "bootstrap.h"
  7. #include <aos/connect/ump.h>
  8. #include <aos_rpc_server/aos_rpc_server_monitor.h>
  9. #include <aos_rpc_server/aos_rpc_server_intermon.h>
  10. errval_t parse_arguments(char *init_args) {
  11. char *current_argument = strtok(init_args, " ");
  12. while (current_argument) {
  13. if (!strcmp("init_args_test", current_argument)) {
  14. debug_printf("Arguments passing test\n");
  15. debug_printf("Received arguments: %s\n", strtok(NULL, ""));
  16. while (true);
  17. break;
  18. }
  19. // TODO jmeier: add handling for other arguments to init
  20. current_argument = strtok(NULL, " ");
  21. }
  22. return SYS_ERR_OK;
  23. }
  24. /** \brief creates the bootinfo and puts it in the well known location
  25. * for APP cores only
  26. * additionally it maps the frame to the global bootinfo pointer
  27. *
  28. * \param bootinfo_base kernel virtual address of bootinfo
  29. * \param bootinfo_size size of bootinfo frame
  30. */
  31. static errval_t setup_bootinfo(genpaddr_t bootinfo_base, gensize_t bootinfo_size) {
  32. assert(bootinfo_base);
  33. errval_t err = frame_forge(cap_bootinfo, bootinfo_base, bootinfo_size, disp_get_core_id());
  34. if (err_is_fail(err)) {
  35. debug_printf("frame forge failedin setup_bootinfo\n");
  36. return err;
  37. }
  38. err = paging_map_frame_attr(get_current_paging_state(), (void *) &bi, bootinfo_size, cap_bootinfo, VREGION_FLAGS_READ, NULL, NULL);
  39. if (err_is_fail(err)) {
  40. debug_printf("bootinfo mapping failed\n");
  41. return err;
  42. }
  43. return SYS_ERR_OK;
  44. }
  45. /** \brief forges the mmstringsraw module capability from
  46. * urpc_init_msg and creates the other modules
  47. * capabilities from the bootinfo
  48. */
  49. static errval_t setup_modules_caps(genpaddr_t mmstrings_base, gensize_t mmstrings_size) {
  50. assert(bi);
  51. genpaddr_t base;
  52. gensize_t size;
  53. errval_t err = cnode_create_foreign_l2(cap_root, ROOTCN_SLOT_MODULECN, NULL);
  54. if (err_is_fail(err)) {
  55. debug_printf("cnode_create_l2 failed for mmstrings\n");
  56. return err;
  57. }
  58. /* Map in multiboot module strings area */
  59. struct capref module_cap = {
  60. .cnode = cnode_module,
  61. .slot = 0
  62. };
  63. coreid_t core_id = disp_get_core_id();
  64. err = frame_forge(module_cap, mmstrings_base, mmstrings_size, core_id);
  65. if (err_is_fail(err)) {
  66. debug_printf("frame forge failed for mmstrings\n");
  67. return err;
  68. }
  69. void *buf;
  70. err = paging_map_frame_attr(get_current_paging_state(), &buf, mmstrings_size, module_cap, VREGION_FLAGS_READ, NULL, NULL);
  71. int i = 0;
  72. while(i < bi->regions_length) {
  73. if (bi->regions[i].mr_type == RegionType_Module) {
  74. base = bi->regions[i].mr_base;
  75. size = bi->regions[i].mrmod_size;
  76. module_cap.slot = bi->regions[i].mrmod_slot;
  77. err = frame_forge(module_cap, base, size, core_id);
  78. if (err_is_fail(err)) {
  79. debug_printf("frame_forge failed for module\n");
  80. return err;
  81. }
  82. }
  83. i++;
  84. }
  85. return SYS_ERR_OK;
  86. }
  87. struct bootstrap_state {
  88. bool done;
  89. struct aos_urpc_chan *urpc_chan;
  90. };
  91. void setup_init_bsp(enum rpc_services_mode mode) {
  92. assert(disp_get_core_id() == 0);
  93. debug_printf("address of bootinfo: %p\n", bi);
  94. debug_printf("bootinfo region length: %u\n", bi->regions_length);
  95. // Initialize physical memory management for boot core
  96. errval_t err = initialize_ram_alloc_bsp(mode);
  97. if (err_is_fail(err)) {
  98. DEBUG_ERR(err, "initialize_ram_alloc_bsp failed.\n");
  99. abort();
  100. }
  101. }
  102. void setup_init_app(routing_info_t intermon_routing) {
  103. assert(0 < disp_get_core_id());
  104. // set local monitor channel
  105. struct aos_rpc *monitor_rpc = malloc(sizeof(*monitor_rpc));
  106. if (!monitor_rpc) {
  107. USER_PANIC_ERR(LIB_ERR_MALLOC_FAIL, "could not initialize local init channel\n");
  108. }
  109. init_local_channel(monitor_rpc, AOS_RPC_INTERFACE_MONITOR, &aos_rpc_monitor_local_vtable);
  110. set_init_rpc(monitor_rpc);
  111. // map the urpc frame from well known urpc cap and establish a full bidirectional
  112. // connection with the bsp core (both offering server and client functionalities)
  113. void *ump_buffer;
  114. errval_t err = paging_map_frame_attr(get_current_paging_state(), &ump_buffer, MON_URPC_SIZE, cap_urpc, VREGION_FLAGS_READ_WRITE, NULL, NULL);
  115. if (err_is_fail(err)) {
  116. USER_PANIC_ERR(err, "urpc mapping failed\n");
  117. }
  118. // note: *NO* clean and in particular *NO* invalidate (which goes to poc) here
  119. // again, first is what is done first, i.e. on core 1: client, then server connection
  120. // note: on core 0, the order is reversed, of course
  121. // also: the ump_chan_init() including handshakes need to be established before
  122. // the actual RPC chan can be established
  123. size_t half = MON_URPC_SIZE >> 1;
  124. void *first = ump_buffer;
  125. void *second = ((char *)ump_buffer) + half;
  126. // again, first is what is done first, i.e. on core 1: client, then server connection
  127. // note: on core 0, the order is reversed, of course
  128. struct aos_rpc *intermon_client;
  129. err = setup_ump_client_from_buffer(first, half,
  130. AOS_RPC_INTERFACE_INTERMON, &aos_rpc_intermon_remote_vtable,
  131. intermon_routing, &intermon_client);
  132. if (err_is_fail(err)) {
  133. USER_PANIC_ERR(err, "setup_ump_client failed\n");
  134. }
  135. set_intermon_rpc(AOS_RPC_ROUTING_SERVER_CORE_ID(intermon_routing), intermon_client);
  136. struct ump_service_create_data data;
  137. err = setup_ump_service_part1_from_buffer(second, half, &data);
  138. if (err_is_fail(err)) {
  139. USER_PANIC_ERR(err, "setup_ump_service_part1 failed\n");
  140. }
  141. // NOTE: deliberately, the monitor handler is used here (which can also handle intermon)
  142. err = setup_ump_service_part2(&data, MKCLOSURE(aos_rpc_monitor_event_handler, NULL));
  143. if (err_is_fail(err)) {
  144. USER_PANIC_ERR(err, "setup_ump_service_part2 failed\n");
  145. }
  146. debug_printf("intermon handshakes completed\n");
  147. //--- get bootstrap info
  148. struct aos_rpc *irpc = aos_rpc_get_intermon_channel(BSP_CORE_ID);
  149. struct aos_intermon_bootstrap_res bootstrap_info;
  150. err = aos_rpc_intermon_request_bootstrap_info(irpc, disp_get_core_id(), &bootstrap_info);
  151. if (err_is_fail(err)) {
  152. USER_PANIC_ERR(err, "could not get bootinfo from BSP core\n");
  153. }
  154. err = setup_bootinfo(bootstrap_info.bootinfo_base, bootstrap_info.bootinfo_size);
  155. if (err_is_fail(err)) {
  156. USER_PANIC_ERR(err, "could not set up bootinfo for APP core\n");
  157. }
  158. debug_printf("bootinfo received\n");
  159. //--- name service
  160. struct capref name_cap;
  161. err = slot_alloc(&name_cap);
  162. if (err_is_fail(err)) {
  163. USER_PANIC_ERR(err, "Cannot allocate slot for frame forgery.\n");
  164. }
  165. // doing some forgery...... psssssst, don't tell anyone
  166. err = frame_forge(name_cap, bootstrap_info.name_base, bootstrap_info.name_size, disp_get_core_id());
  167. if (err_is_fail(err)) {
  168. USER_PANIC_ERR(err, "Cannot forge frame\n");
  169. }
  170. struct aos_rpc *name_rpc;
  171. err = aos_rpc_connect_with_service(name_cap, AOS_RPC_INTERFACE_NAME, AOS_RPC_CHAN_DRIVER_UMP,
  172. intermon_routing, &name_rpc, NULL);
  173. if (err_is_fail(err)) {
  174. USER_PANIC_ERR(err, "Cannot connect with name service\n");
  175. }
  176. set_name_rpc(name_rpc);
  177. debug_printf("Connected with name service\n");
  178. //--- memory service, including switch of default RAM allocator to Dionysos
  179. // using name service and late binding
  180. struct aos_rpc *mem_rpc = aos_rpc_get_memory_channel();
  181. if (!mem_rpc) {
  182. USER_PANIC_ERR(err, "Cannot connect with Memory service on core 0.\n");
  183. }
  184. debug_printf("mem_rpc here\n");
  185. // note: no late switching for monitors because they need
  186. // different RAM sizes early on. Thus: better check & test here that all works
  187. err = ram_alloc_set(NULL);
  188. if (err_is_fail(err)) {
  189. USER_PANIC_ERR(err, "Cannot set ram_allocator.\n");
  190. }
  191. debug_printf("Connected with memory service\n");
  192. // test memory system
  193. debug_printf("Testing memory service\n");
  194. void *test = calloc(1, 8000);
  195. if (!test) {
  196. USER_PANIC_ERR(LIB_ERR_MALLOC_FAIL, "memory system not fully working\n");
  197. }
  198. free(test);
  199. debug_printf("Memory service tested\n");
  200. // initialize all module capabilities on order to spawn on second core
  201. err = setup_modules_caps(bootstrap_info.mmstrings_base, bootstrap_info.mmstrings_size);
  202. if (err_is_fail(err)) {
  203. USER_PANIC_ERR(err, "could not initialize module capabilities on APP core\n");
  204. }
  205. // register after setup is complete (function defined in bootstrap.c)
  206. err = register_monitor();
  207. if (err_is_fail(err)) {
  208. USER_PANIC_ERR(err, "Cannot register to name service\n");
  209. }
  210. debug_printf("setup & registration complete\n");
  211. }