123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- /* https://cirosantilli.com/linux-kernel-module-cheat#lkmc-c */
- #include <math.h>
- #include <stdio.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <lkmc.h>
- #define LKMC_ASSERT_EQ_DEFINE(bits) \
- LKMC_ASSERT_EQ_DECLARE(bits) \
- { \
- if (val1 != val2) { \
- printf("%s failed\n", __func__); \
- printf("val1 0x%" PRIX ## bits "\n", val1); \
- printf("val2 0x%" PRIX ## bits "\n", val2); \
- lkmc_assert_fail(line); \
- } \
- }
- LKMC_ASSERT_EQ_DEFINE(32)
- LKMC_ASSERT_EQ_DEFINE(64)
- #undef ASSERT_EQ_DEFINE
- void lkmc_assert_fail(uint32_t line) {
- printf("error: assertion failed at line: %" PRIu32 "\n", line);
- fflush(stdout);
- abort();
- }
- void lkmc_assert_memcmp(
- const void *s1,
- const void *s2,
- size_t n,
- uint32_t line
- ) {
- size_t i;
- uint8_t *s1b, *s2b;
- uint8_t b1, b2;
- s1b = (uint8_t *)s1;
- s2b = (uint8_t *)s2;
- for (i = 0; i < n; ++i) {
- b1 = s1b[i];
- b2 = s2b[i];
- if (b1 != b2) {
- printf(
- "%s failed: "
- "byte1, byte2, index: "
- "0x%02" PRIX8 " 0x%02" PRIX8 " 0x%zX\n",
- __func__,
- b1,
- b2,
- i
- );
- lkmc_assert_fail(line);
- }
- }
- }
- void lkmc_print_hex_32(uint32_t x) {
- printf("0x%08" PRIX32, x);
- }
- void lkmc_print_hex_64(uint64_t x) {
- printf("0x%016" PRIX64, x);
- }
- void lkmc_print_newline() {
- printf("\n");
- }
- #if defined(__arm__)
- void lkmc_arm_psci_cpu_on(
- uint32_t target_cpu,
- uint32_t entry_point_address,
- uint32_t context_id
- ) {
- register int r0 __asm__ ("r0") = 0x84000003;
- register int r1 __asm__ ("r1") = target_cpu;
- register int r2 __asm__ ("r2") = entry_point_address;
- register int r3 __asm__ ("r3") = context_id;
- __asm__ __volatile__(
- "hvc 0\n"
- :
- : "r" (r0),
- "r" (r1),
- "r" (r2),
- "r" (r3)
- :
- );
- }
- #elif defined(__aarch64__)
- #define LKMC_SYSREG_READ_WRITE(nbits, name) \
- LKMC_CONCAT(LKMC_CONCAT(uint, nbits), _t) LKMC_CONCAT(LKMC_CONCAT(LKMC_SYSREG_SYMBOL_PREFIX, read_), name)(void) { \
- LKMC_CONCAT(LKMC_CONCAT(uint, nbits), _t) name; \
- __asm__ __volatile__("mrs %0, " #name : "=r" (name) : : ); \
- return name; \
- } \
- void LKMC_CONCAT(LKMC_CONCAT(LKMC_SYSREG_SYMBOL_PREFIX, write_), name)(LKMC_CONCAT(LKMC_CONCAT(uint, nbits), _t) name) { \
- __asm__ __volatile__("msr " #name ", %0" : : "r" (name) : ); \
- } \
- void LKMC_CONCAT(LKMC_CONCAT(LKMC_SYSREG_SYMBOL_PREFIX, print_), name)(void) { \
- printf(#name " 0x%" PRIX ## nbits "\n", LKMC_CONCAT(LKMC_CONCAT(LKMC_SYSREG_SYMBOL_PREFIX, read_), name)()); \
- }
- LKMC_SYSREG_OPS
- #undef LKMC_SYSREG_READ_WRITE
- uint64_t lkmc_aarch64_cpu_id() {
- /* TODO: cores beyond 4th?
- * Mnemonic: Main Processor ID Register
- */
- return lkmc_sysreg_read_mpidr_el1() & 3;
- }
- void lkmc_aarch64_psci_cpu_on(
- uint64_t target_cpu,
- uint64_t entry_point_address,
- uint64_t context_id
- ) {
- register int w0 __asm__ ("w0") = 0xc4000003;
- register int x1 __asm__ ("x1") = target_cpu;
- register int x2 __asm__ ("x2") = entry_point_address;
- register int x3 __asm__ ("x3") = context_id;
- __asm__ __volatile__(
- "hvc 0\n"
- :
- : "r" (w0),
- "r" (x1),
- "r" (x2),
- "r" (x3)
- :
- );
- }
- #endif
|