refcode.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * Read a coreboot rmodule and execute it.
  3. * The rmodule_header struct is from coreboot.
  4. *
  5. * Copyright (c) 2016 Google, Inc
  6. *
  7. * SPDX-License-Identifier: GPL-2.0
  8. */
  9. #include <common.h>
  10. #include <errno.h>
  11. #include <asm/arch/pei_data.h>
  12. #define RMODULE_MAGIC 0xf8fe
  13. #define RMODULE_VERSION_1 1
  14. /*
  15. * All fields with '_offset' in the name are byte offsets into the flat blob.
  16. * The linker and the linker script takes are of assigning the values.
  17. */
  18. struct rmodule_header {
  19. uint16_t magic;
  20. uint8_t version;
  21. uint8_t type;
  22. /* The payload represents the program's loadable code and data */
  23. uint32_t payload_begin_offset;
  24. uint32_t payload_end_offset;
  25. /* Begin and of relocation information about the program module */
  26. uint32_t relocations_begin_offset;
  27. uint32_t relocations_end_offset;
  28. /*
  29. * The starting address of the linked program. This address is vital
  30. * for determining relocation offsets as the relocation info and other
  31. * symbols (bss, entry point) need this value as a basis to calculate
  32. * the offsets.
  33. */
  34. uint32_t module_link_start_address;
  35. /*
  36. * The module_program_size is the size of memory used while running
  37. * the program. The program is assumed to consume a contiguous amount
  38. * of memory
  39. */
  40. uint32_t module_program_size;
  41. /* This is program's execution entry point */
  42. uint32_t module_entry_point;
  43. /*
  44. * Optional parameter structure that can be used to pass data into
  45. * the module
  46. */
  47. uint32_t parameters_begin;
  48. uint32_t parameters_end;
  49. /* BSS section information so the loader can clear the bss */
  50. uint32_t bss_begin;
  51. uint32_t bss_end;
  52. /* Add some room for growth */
  53. uint32_t padding[4];
  54. } __packed;
  55. int cpu_run_reference_code(void)
  56. {
  57. struct pei_data _pei_data __aligned(8);
  58. struct pei_data *pei_data = &_pei_data;
  59. asmlinkage int (*func)(void *);
  60. struct rmodule_header *hdr;
  61. char *src, *dest;
  62. int ret, dummy;
  63. int size;
  64. hdr = (struct rmodule_header *)CONFIG_X86_REFCODE_ADDR;
  65. debug("Extracting code from rmodule at %p\n", hdr);
  66. if (hdr->magic != RMODULE_MAGIC) {
  67. debug("Invalid rmodule magic\n");
  68. return -EINVAL;
  69. }
  70. if (hdr->module_link_start_address != 0) {
  71. debug("Link start address must be 0\n");
  72. return -EPERM;
  73. }
  74. if (hdr->module_entry_point != 0) {
  75. debug("Entry point must be 0\n");
  76. return -EPERM;
  77. }
  78. memset(pei_data, '\0', sizeof(struct pei_data));
  79. broadwell_fill_pei_data(pei_data);
  80. mainboard_fill_pei_data(pei_data);
  81. pei_data->saved_data = (void *)&dummy;
  82. src = (char *)hdr + hdr->payload_begin_offset;
  83. dest = (char *)CONFIG_X86_REFCODE_RUN_ADDR;
  84. size = hdr->payload_end_offset - hdr->payload_begin_offset;
  85. debug("Copying refcode from %p to %p, size %x\n", src, dest, size);
  86. memcpy(dest, src, size);
  87. size = hdr->bss_end - hdr->bss_begin;
  88. debug("Zeroing BSS at %p, size %x\n", dest + hdr->bss_begin, size);
  89. memset(dest + hdr->bss_begin, '\0', size);
  90. func = (asmlinkage int (*)(void *))dest;
  91. debug("Running reference code at %p\n", func);
  92. #ifdef DEBUG
  93. print_buffer(CONFIG_X86_REFCODE_RUN_ADDR, (void *)func, 1, 0x40, 0);
  94. #endif
  95. ret = func(pei_data);
  96. if (ret != 0) {
  97. debug("Reference code returned %d\n", ret);
  98. return -EL2HLT;
  99. }
  100. debug("Refereence code completed\n");
  101. return 0;
  102. }