X-Git-Url: http://git.ozlabs.org/?p=yaboot.git;a=blobdiff_plain;f=second%2Fprom.c;h=e9c5843e1efec04b25baa7185e16a9025b8e0905;hp=8cb8a41951a8fc9460d3543a30a46f7acb757a57;hb=1bea6140c2894b1259fd07f323b25fd846bd5acf;hpb=778a7e33cfa273b52c5b6256e61da1e00303d304 diff --git a/second/prom.c b/second/prom.c index 8cb8a41..e9c5843 100644 --- a/second/prom.c +++ b/second/prom.c @@ -33,6 +33,7 @@ #include "asm/processor.h" #include "errors.h" #include "debug.h" +#include "string.h" #define READ_BLOCKS_USE_READ 1 @@ -153,6 +154,18 @@ prom_getprop (prom_handle pack, char *name, void *mem, int len) return (int)call_prom ("getprop", 4, 1, pack, name, mem, len); } +int +prom_getproplen(prom_handle pack, const char *name) +{ + return (int)call_prom("getproplen", 2, 1, pack, name); +} + +int +prom_setprop (prom_handle pack, char *name, void *mem, int len) +{ + return (int)call_prom ("setprop", 4, 1, pack, name, mem, len); +} + int prom_get_chosen (char *name, void *mem, int len) { @@ -167,6 +180,14 @@ prom_get_options (char *name, void *mem, int len) return prom_getprop (prom_options, name, mem, len); } +int +prom_set_options (char *name, void *mem, int len) +{ + if (prom_options == (void *)-1) + return -1; + return prom_setprop (prom_options, name, mem, len); +} + int prom_get_devtype (char *device) { @@ -634,6 +655,102 @@ prom_pause(void) call_prom("enter", 0, 0); } +/* + * prom_get_netinfo() + * returns the packet with all needed info for netboot + */ +struct bootp_packet * prom_get_netinfo (void) +{ + void *bootp_response = NULL; + char *propname; + struct bootp_packet *packet; + int i = 0, size, offset = 0; + prom_handle chosen; +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + + chosen = prom_finddevice("/chosen"); + if (chosen < 0) { + DEBUG_F("chosen=%d\n", chosen); + return 0; + } + + for (i = 0; i < ARRAY_SIZE(bootp_response_properties); i++) { + propname = bootp_response_properties[i].name; + size = prom_getproplen(chosen, propname); + if (size <= 0) + continue; + + DEBUG_F("using /chosen/%s\n", propname); + offset = bootp_response_properties[i].offset; + break; + } + + if (size <= 0) + return NULL; + + if (sizeof(*packet) > size - offset) { + prom_printf("Malformed %s property?\n", propname); + return NULL; + } + + bootp_response = malloc(size); + if (!bootp_response) + return NULL; + + if (prom_getprop(chosen, propname, bootp_response, size) < 0) + return NULL; + + packet = bootp_response + offset; + return packet; +} + +/* + * prom_get_mac() + * returns the mac addr of an net card + */ +char * prom_get_mac (struct bootp_packet * packet) +{ + char * conf_path; + int i; + + if (!packet) + return NULL; + + /* 3 chars per byte in chaddr + \0 */ + conf_path = malloc(packet->hlen * 3 + 1); + if (!conf_path) + return NULL; + sprintf(conf_path, "%02x", packet->chaddr[0]); + + for (i = 1; i < packet->hlen; i++) { + char tmp[4]; + sprintf(tmp, "-%02x", packet->chaddr[i]); + strcat(conf_path, tmp); + } + + return conf_path; +} + +/* + * prom_get_ip() + * returns the ip addr of an net card + */ +char * prom_get_ip (struct bootp_packet * packet) +{ + char * conf_path; + + if (!packet) + return NULL; + + /* 8 chars in yiaddr + \0 */ + conf_path = malloc(9); + if (!conf_path) + return NULL; + sprintf(conf_path, "%08x", packet->yiaddr); + + return conf_path; +} + /* * Local variables: * c-file-style: "k&r"