From e0dc16c217b3d7f98165ff2c7473c9222c879354 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Fri, 9 Sep 2016 21:52:03 +0200 Subject: paflof: Add socket(), send() and recv() functions to paflof 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 Signed-off-by: Alexey Kardashevskiy --- slof/ppc64.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) (limited to 'slof') 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 +#include #include 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"); +} -- cgit v1.1