natfeat.c 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  2. * natfeat.c - ARAnyM hardware support via Native Features (natfeats)
  3. *
  4. * Copyright (c) 2005 Petr Stehlik of ARAnyM dev team
  5. *
  6. * Reworked for Linux by Roman Zippel <zippel@linux-m68k.org>
  7. *
  8. * This software may be used and distributed according to the terms of
  9. * the GNU General Public License (GPL), incorporated herein by reference.
  10. */
  11. #include <linux/init.h>
  12. #include <linux/types.h>
  13. #include <linux/console.h>
  14. #include <linux/string.h>
  15. #include <linux/kernel.h>
  16. #include <linux/module.h>
  17. #include <linux/io.h>
  18. #include <asm/machdep.h>
  19. #include <asm/natfeat.h>
  20. extern long nf_get_id_phys(unsigned long feature_name);
  21. asm("\n"
  22. " .global nf_get_id_phys,nf_call\n"
  23. "nf_get_id_phys:\n"
  24. " .short 0x7300\n"
  25. " rts\n"
  26. "nf_call:\n"
  27. " .short 0x7301\n"
  28. " rts\n"
  29. "1: moveq.l #0,%d0\n"
  30. " rts\n"
  31. " .section __ex_table,\"a\"\n"
  32. " .long nf_get_id_phys,1b\n"
  33. " .long nf_call,1b\n"
  34. " .previous");
  35. EXPORT_SYMBOL_GPL(nf_call);
  36. long nf_get_id(const char *feature_name)
  37. {
  38. /* feature_name may be in vmalloc()ed memory, so make a copy */
  39. char name_copy[32];
  40. size_t n;
  41. n = strlcpy(name_copy, feature_name, sizeof(name_copy));
  42. if (n >= sizeof(name_copy))
  43. return 0;
  44. return nf_get_id_phys(virt_to_phys(name_copy));
  45. }
  46. EXPORT_SYMBOL_GPL(nf_get_id);
  47. void nfprint(const char *fmt, ...)
  48. {
  49. static char buf[256];
  50. va_list ap;
  51. int n;
  52. va_start(ap, fmt);
  53. n = vsnprintf(buf, 256, fmt, ap);
  54. nf_call(nf_get_id("NF_STDERR"), virt_to_phys(buf));
  55. va_end(ap);
  56. }
  57. static void nf_poweroff(void)
  58. {
  59. long id = nf_get_id("NF_SHUTDOWN");
  60. if (id)
  61. nf_call(id);
  62. }
  63. void __init nf_init(void)
  64. {
  65. unsigned long id, version;
  66. char buf[256];
  67. id = nf_get_id("NF_VERSION");
  68. if (!id)
  69. return;
  70. version = nf_call(id);
  71. id = nf_get_id("NF_NAME");
  72. if (!id)
  73. return;
  74. nf_call(id, virt_to_phys(buf), 256);
  75. buf[255] = 0;
  76. pr_info("NatFeats found (%s, %lu.%lu)\n", buf, version >> 16,
  77. version & 0xffff);
  78. mach_power_off = nf_poweroff;
  79. }