Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | /* * Copyright 1996 The Australian National University. * Copyright 1996 Fujitsu Laboratories Limited * * This software may be distributed under the terms of the Gnu * Public License version 2 or later */ /* * fake a really simple Sun prom for the AP+ * */ #include <linux/kernel.h> #include <linux/string.h> #include <asm/oplib.h> #include <asm/idprom.h> #include <asm/machines.h> #include <asm/ap1000/apservice.h> static struct linux_romvec ap_romvec; static struct idprom ap_idprom; struct property { char *name; char *value; int length; }; struct node { int level; struct property *properties; }; struct property null_properties = { NULL, NULL, -1 }; struct property root_properties[] = { {"device_type", "cpu", 4}, {"idprom", (char *)&ap_idprom, sizeof(ap_idprom)}, {"banner-name", "Fujitsu AP1000+", 16}, {NULL, NULL, -1} }; struct node nodes[] = { { 0, &null_properties }, { 0, root_properties }, { -1,&null_properties } }; static int no_nextnode(int node) { if (nodes[node].level == nodes[node+1].level) return node+1; return -1; } static int no_child(int node) { if (nodes[node].level == nodes[node+1].level-1) return node+1; return -1; } static struct property *find_property(int node,char *name) { struct property *prop = &nodes[node].properties[0]; while (prop && prop->name) { if (strcmp(prop->name,name) == 0) return prop; prop++; } return NULL; } static int no_proplen(int node,char *name) { struct property *prop = find_property(node,name); if (prop) return prop->length; return -1; } static int no_getprop(int node,char *name,char *value) { struct property *prop = find_property(node,name); if (prop) { memcpy(value,prop->value,prop->length); return 1; } return -1; } static int no_setprop(int node,char *name,char *value,int len) { return -1; } static char *no_nextprop(int node,char *name) { struct property *prop = find_property(node,name); if (prop) return prop[1].name; return NULL; } static struct linux_nodeops ap_nodeops = { no_nextnode, no_child, no_proplen, no_getprop, no_setprop, no_nextprop }; static unsigned char calc_idprom_cksum(struct idprom *idprom) { unsigned char cksum, i, *ptr = (unsigned char *)idprom; for (i = cksum = 0; i <= 0x0E; i++) cksum ^= *ptr++; return cksum; } static int synch_hook; struct linux_romvec *ap_prom_init(void) { memset(&ap_romvec,0,sizeof(ap_romvec)); ap_romvec.pv_romvers = 42; ap_romvec.pv_nodeops = &ap_nodeops; ap_romvec.pv_reboot = ap_reboot; ap_romvec.pv_synchook = &synch_hook; ap_idprom.id_format = 1; ap_idprom.id_sernum = mpp_cid(); ap_idprom.id_machtype = SM_SUN4M_OBP; ap_idprom.id_cksum = calc_idprom_cksum(&ap_idprom); return &ap_romvec; } |