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 asm("\n" 22 " .global nf_get_id,nf_call\n" 23 "nf_get_id:\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,1b\n" 33 " .long nf_call,1b\n" 34 " .previous"); 35 EXPORT_SYMBOL_GPL(nf_get_id); 36 EXPORT_SYMBOL_GPL(nf_call); 37 38 static int stderr_id; 39 40 static void nf_write(struct console *co, const char *str, unsigned int count) 41 { 42 char buf[68]; 43 44 buf[64] = 0; 45 while (count > 64) { 46 memcpy(buf, str, 64); 47 nf_call(stderr_id, buf); 48 str += 64; 49 count -= 64; 50 } 51 memcpy(buf, str, count); 52 buf[count] = 0; 53 nf_call(stderr_id, buf); 54 } 55 56 void nfprint(const char *fmt, ...) 57 { 58 static char buf[256]; 59 va_list ap; 60 int n; 61 62 va_start(ap, fmt); 63 n = vsnprintf(buf, 256, fmt, ap); 64 nf_call(nf_get_id("NF_STDERR"), buf); 65 va_end(ap); 66 } 67 68 static struct console nf_console_driver = { 69 .name = "debug", 70 .write = nf_write, 71 .flags = CON_PRINTBUFFER, 72 .index = -1, 73 }; 74 75 static int __init nf_debug_setup(char *arg) 76 { 77 if (strcmp(arg, "emu")) 78 return 0; 79 80 stderr_id = nf_get_id("NF_STDERR"); 81 if (stderr_id) 82 register_console(&nf_console_driver); 83 return 0; 84 } 85 86 early_param("debug", nf_debug_setup); 87 88 static void nf_poweroff(void) 89 { 90 long id = nf_get_id("NF_SHUTDOWN"); 91 92 if (id) 93 nf_call(id); 94 } 95 96 void nf_init(void) 97 { 98 unsigned long id, version; 99 char buf[256]; 100 101 id = nf_get_id("NF_VERSION"); 102 if (!id) 103 return; 104 version = nf_call(id); 105 106 id = nf_get_id("NF_NAME"); 107 if (!id) 108 return; 109 nf_call(id, buf, 256); 110 buf[255] = 0; 111 112 pr_info("NatFeats found (%s, %lu.%lu)\n", buf, version >> 16, 113 version & 0xffff); 114 115 mach_power_off = nf_poweroff; 116 } 117