prom functions
authorPaul Nasrat <pnasrat@redhat.com>
Tue, 15 May 2007 13:23:26 +0000 (14:23 +0100)
committerPaul Nasrat <pauln@enki.eridu>
Tue, 15 May 2007 13:23:26 +0000 (14:23 +0100)
This first part creates the prom_get_netinfo (), prom_get_mac (),
prom_get_ip () functions, and some structures to get the necessary
information about the MAC and IP addresses.

Actually, this is a reallocation of netbooting like PXE algorithm wrote
by Benoit Guillon [1], to be used by any other part of Yaboot to get the
netbooting information.

[1] http://ozlabs.org/pipermail/yaboot-devel/2006-December/000062.html

Signed-off-by: Paulo Ricardo Paz Vital <vital@br.ibm.com>
include/prom.h
second/prom.c

index e7ee4a9..f5ee88f 100644 (file)
@@ -27,6 +27,7 @@
 #ifndef PROM_H
 #define PROM_H
 
+#include "types.h"
 #include "stdarg.h"
 
 typedef void *prom_handle;
@@ -118,4 +119,40 @@ extern void prom_pause(void);
 extern void *call_prom (const char *service, int nargs, int nret, ...);
 extern void *call_prom_return (const char *service, int nargs, int nret, ...);
 
+/* Netboot stuffs */
+
+/*
+ * "bootp-response" is the property name which is specified in
+ * the recommended practice doc for obp-tftp. However, pmac
+ * provides a "dhcp-response" property and chrp provides a
+ * "bootpreply-packet" property.  The latter appears to begin the
+ * bootp packet at offset 0x2a in the property for some reason.
+ */
+
+struct bootp_property_offset {
+     char *name; /* property name */
+     int offset; /* offset into property where bootp packet occurs */
+};
+
+static const struct bootp_property_offset bootp_response_properties[] = {
+     { .name = "bootp-response", .offset = 0 },
+     { .name = "dhcp-response", .offset = 0 },
+     { .name = "bootpreply-packet", .offset = 0x2a },
+};
+
+struct bootp_packet {
+     __u8 op, htype, hlen, hops;
+     __u32 xid;
+     __u16 secs, flags;
+     __u32 ciaddr, yiaddr, siaddr, giaddr;
+     unsigned char chaddr[16];
+     unsigned char sname[64];
+     unsigned char file[128];
+     /* vendor options go here if we need them */
+};
+
+struct bootp_packet * prom_get_netinfo (void);
+char * prom_get_mac (struct bootp_packet * packet);
+char * prom_get_ip (struct bootp_packet * packet);
+
 #endif
index 3407e5a..74bbac6 100644 (file)
@@ -654,6 +654,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"