[SLOF] [PATCH 05/11] paflof: Add socket(), send() and recv() functions to paflof

Thomas Huth thuth at redhat.com
Sat Sep 10 05:52:03 AEST 2016


Code is slightly based on the implementation from net-snk, but
has been adapted to use the forth_eval() and forth_push/pop() macros
instead.

Signed-off-by: Thomas Huth <thuth at redhat.com>
---
 {clients/net-snk => lib/libc}/include/sys/socket.h |   0
 slof/ppc64.c                                       | 110 +++++++++++++++++++++
 2 files changed, 110 insertions(+)
 rename {clients/net-snk => lib/libc}/include/sys/socket.h (100%)

diff --git a/clients/net-snk/include/sys/socket.h b/lib/libc/include/sys/socket.h
similarity index 100%
rename from clients/net-snk/include/sys/socket.h
rename to lib/libc/include/sys/socket.h
diff --git a/slof/ppc64.c b/slof/ppc64.c
index 4fc92b9..7169cb0 100644
--- a/slof/ppc64.c
+++ b/slof/ppc64.c
@@ -11,6 +11,7 @@
  *****************************************************************************/
 
 #include <unistd.h>
+#include <sys/socket.h>
 #include <cpu.h>
 
 void asm_cout(long Character,long UART,long NVRAM);
@@ -92,3 +93,112 @@ asm_cout(long Character, long UART, long NVRAM __attribute__((unused)))
 	if (UART)
 		io_putchar(Character);
 }
+
+#define FILEIO_TYPE_EMPTY   0
+#define FILEIO_TYPE_FILE    1
+#define FILEIO_TYPE_SOCKET  2
+
+struct fileio_type {
+	int type;
+	int ih;		/* ihandle */
+};
+
+#define FILEIO_MAX 32
+static struct fileio_type fd_array[FILEIO_MAX];
+
+int socket(int domain, int type, int proto, char *mac_addr)
+{
+	const char mac_prop_name[] = "local-mac-address";
+	uint8_t *prop_addr;
+	int prop_len;
+	int fd;
+
+	/* search free file descriptor (and skip stdio handlers) */
+	for (fd = 3; fd < FILEIO_MAX; ++fd) {
+		if (fd_array[fd].type == FILEIO_TYPE_EMPTY) {
+			break;
+		}
+	}
+	if (fd == FILEIO_MAX) {
+		puts("Can not open socket, file descriptor list is full");
+		return -2;
+	}
+
+	forth_eval("my-parent");
+	fd_array[fd].ih = forth_pop();
+	if (fd_array[fd].ih == 0) {
+		puts("Can not open socket, no parent instance");
+		return -1;
+	}
+
+	/* Read MAC address from device */
+	forth_push((unsigned long)mac_prop_name);
+	forth_push(strlen(mac_prop_name));
+	forth_push(fd_array[fd].ih);
+	forth_eval("ihandle>phandle get-property");
+	if (forth_pop())
+		return -1;
+	prop_len = forth_pop();
+	prop_addr = (uint8_t *)forth_pop();
+	memcpy(mac_addr, &prop_addr[prop_len - 6], 6);
+
+	fd_array[fd].type = FILEIO_TYPE_SOCKET;
+
+	return fd;
+}
+
+static inline int is_valid_fd(int fd)
+{
+	return fd >= 0 && fd < FILEIO_MAX &&
+	       fd_array[fd].type != FILEIO_TYPE_EMPTY;
+}
+
+int close(int fd)
+{
+	if (!is_valid_fd(fd))
+		return -1;
+
+	fd_array[fd].type = FILEIO_TYPE_EMPTY;
+
+	return 0;
+}
+
+/**
+ * Standard recv function for the libc.
+ *
+ * @param fd     socket file descriptor
+ * @param buf    pointer to the array where the packet should be stored
+ * @param len    maximum length in bytes of the packet
+ * @param flags  currently unused, should be 0
+ * @return       the number of bytes that have been received successfully
+ */
+int recv(int fd, void *buf, int len, int flags)
+{
+	if (!is_valid_fd(fd))
+		return -1;
+
+	forth_push((unsigned long)buf);
+	forth_push(len);
+
+	return forth_eval_pop("read");
+}
+
+/**
+ * Standard send function for the libc.
+ *
+ * @param fd     socket file descriptor
+ * @param buf    pointer to the array with the output packet
+ * @param len    length in bytes of the packet
+ * @param flags  currently unused, should be 0
+ * @return       the number of bytes that have been sent successfully
+ */
+int send(int fd, const void *buf, int len, int flags)
+{
+	if (!is_valid_fd(fd))
+		return -1;
+
+	forth_push((unsigned long)buf);
+	forth_push(len);
+
+	return forth_eval_pop("write");
+}
-- 
1.8.3.1



More information about the SLOF mailing list