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 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 21 extern long nf_get_id_phys(unsigned long feature_name); 22 23 asm("\n" 24 " .global nf_get_id_phys,nf_call\n" 25 "nf_get_id_phys:\n" 26 " .short 0x7300\n" 27 " rts\n" 28 "nf_call:\n" 29 " .short 0x7301\n" 30 " rts\n" 31 "1: moveq.l #0,%d0\n" 32 " rts\n" 33 " .section __ex_table,\"a\"\n" 34 " .long nf_get_id_phys,1b\n" 35 " .long nf_call,1b\n" 36 " .previous"); 37 EXPORT_SYMBOL_GPL(nf_call); 38 39 long nf_get_id(const char *feature_name) 40 { 41 /* feature_name may be in vmalloc()ed memory, so make a copy */ 42 char name_copy[32]; 43 size_t n; 44 45 n = strlcpy(name_copy, feature_name, sizeof(name_copy)); 46 if (n >= sizeof(name_copy)) 47 return 0; 48 49 return nf_get_id_phys(virt_to_phys(name_copy)); 50 } 51 EXPORT_SYMBOL_GPL(nf_get_id); 52 53 void nfprint(const char *fmt, ...) 54 { 55 static char buf[256]; 56 va_list ap; 57 int n; 58 59 va_start(ap, fmt); 60 n = vsnprintf(buf, 256, fmt, ap); 61 nf_call(nf_get_id("NF_STDERR"), virt_to_phys(buf)); 62 va_end(ap); 63 } 64 65 static void nf_poweroff(void) 66 { 67 long id = nf_get_id("NF_SHUTDOWN"); 68 69 if (id) 70 nf_call(id); 71 } 72 73 void nf_init(void) 74 { 75 unsigned long id, version; 76 char buf[256]; 77 78 id = nf_get_id("NF_VERSION"); 79 if (!id) 80 return; 81 version = nf_call(id); 82 83 id = nf_get_id("NF_NAME"); 84 if (!id) 85 return; 86 nf_call(id, virt_to_phys(buf), 256); 87 buf[255] = 0; 88 89 pr_info("NatFeats found (%s, %lu.%lu)\n", buf, version >> 16, 90 version & 0xffff); 91 92 mach_power_off = nf_poweroff; 93 } 94