From 74cfa5f9498a0b23252b79ee21c3bd864f944426 Mon Sep 17 00:00:00 2001 From: Lucas Schumacher Date: Tue, 29 Apr 2025 18:53:48 -0400 Subject: [PATCH] Add socket support for mips --- arch/mips.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++ socktest.c | 11 ++++- sys.h | 49 +++++++++++++----- 3 files changed, 187 insertions(+), 13 deletions(-) diff --git a/arch/mips.c b/arch/mips.c index 91ca092..0ef5e37 100644 --- a/arch/mips.c +++ b/arch/mips.c @@ -102,4 +102,144 @@ int fsync(unsigned int fd){ return rtn; } +int socket(int domain, int type, int protocol){ + int sockfd = 0; + asm volatile ( + "move $a0, %1\n" + "move $a1, %2\n" + "move $a2, %3\n" + "li $v0, 4183\n" + "syscall\n" + "move %0, $v0\n" + : "=r"(sockfd) + : "r"(domain), "r"(type), "r"(protocol) + : "a0", "a1", "a2", "v0", "memory" + ); + return sockfd; +} + +int setsockopt(int sockfd, int level, int optname, const void* optval, socklen_t optlen){ + int rtn = 0; + asm volatile ( + "li $v0, 4181\n" + "move $a0, %1\n" + "move $a1, %2\n" + "move $a2, %3\n" + "move $a3, %4\n" + "addiu $sp, $sp, -32\n" + "sw %5, 16($sp)\n" + "syscall\n" + "addiu $sp, $sp, 32\n" + "move %0, $v0\n" + : "=r"(rtn) + : "r"(sockfd), "r"(level), "r"(optname), "r"(optval), "r"(optlen) + : "a0", "a1", "a2", "a3", "t0", "v0" + ); + return rtn; +} + +int bind(int sockfd, const void* sockaddr, socklen_t addrlen) { + int rtn = 0; + asm volatile ( + "move $a0, %1\n" + "move $a1, %2\n" + "move $a2, %3\n" + "li $v0, 4169\n" + "syscall\n" + "move %0, $v0\n" + : "=r"(rtn) + : "r"(sockfd), "r"(sockaddr), "r"(addrlen) + : "a0", "a1", "a2", "v0" + ); + return rtn; +} + +int listen(int fd, int backlog) { + int rtn = 0; + asm volatile ( + "move $a0, %1\n" + "move $a1, %2\n" + "li $v0, 4174\n" + "syscall\n" + "move %0, $v0\n" + : "=r"(rtn) + : "r"(fd), "r"(backlog) + : "a0", "a1", "v0" + ); + return rtn; +} + +int accept(int sockfd, void* addr, socklen_t* addrlen) { + int connfd = 0; + asm volatile ( + "move $a0, %1\n" + "move $a1, %2\n" + "move $a2, %3\n" + "li $v0, 4168\n" + "syscall\n" + "move %0, $v0\n" + : "=r"(connfd) + : "r"(sockfd), "r"(addr), "r"(addrlen) + : "a0", "a1", "a2", "v0", "memory" + ); + return connfd; +} + +int connect(int sockfd, void* addr, socklen_t addrlen) { + int connfd = 0; + asm volatile ( + "move $a0, %1\n" + "move $a1, %2\n" + "move $a2, %3\n" + "li $v0, 4170\n" + "syscall\n" + "move %0, $v0\n" + : "=r"(connfd) + : "r"(sockfd), "r"(addr), "r"(addrlen) + : "a0", "a1", "a2", "v0" + ); + return connfd; +} + +ssize_t sendto(int sockfd, const void* buf, size_t size, int flags, const void* sockaddr, socklen_t addrlen){ + ssize_t rtn = 0; + asm volatile ( + "li $v0, 4180\n" + "move $a0, %1\n" + "move $a1, %2\n" + "move $a2, %3\n" + "move $a3, %4\n" + "addiu $sp, $sp, -32\n" + "sw %5, 16($sp)\n" + "sw %6, 20($sp)\n" + "syscall\n" + "addiu $sp, $sp, 32\n" + "move %0, $v0\n" + : "=r"(rtn) + : "r"(sockfd), "r"(buf), "r"(size), "r"(flags), "r"(sockaddr), "r"(addrlen) + : "a0", "a1", "a2", "a3", "t0", "t1", "v0" + ); + return rtn; +} +ssize_t recvfrom(int sockfd, const void* buf, size_t size, int flags, const void* sockaddr, socklen_t addrlen){ + ssize_t rtn = 0; + asm volatile ( + "li $v0, 4176\n" + "move $a0, %1\n" + "move $a1, %2\n" + "move $a2, %3\n" + "move $a3, %4\n" + "addiu $sp, $sp, -32\n" + "sw %5, 16($sp)\n" + "sw %6, 20($sp)\n" + "syscall\n" + "addiu $sp, $sp, 32\n" + "move %0, $v0\n" + : "=r"(rtn) + : "r"(sockfd), "r"(buf), "r"(size), "r"(flags), "r"(sockaddr), "r"(addrlen) + : "a0", "a1", "a2", "a3", "t0", "t1", "v0", "memory" + ); + return rtn; +} + #endif diff --git a/socktest.c b/socktest.c index 5425a7e..4e510bb 100644 --- a/socktest.c +++ b/socktest.c @@ -8,8 +8,12 @@ int main() { struct sockaddr_in server, client; server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; - //server.sin_port = htons( 6969 ); + + #if defined(__mips__) + server.sin_port = 6969; + #else server.sin_port = 0x391b; + #endif // Create the socket socket_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); @@ -21,7 +25,7 @@ int main() { // Set socket options int opt = 1; - if(0 > setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { + if(0 > setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(optlen))) { write(STDERR, "Socket error\n", 13); close(socket_fd); return 2; @@ -89,3 +93,6 @@ int main() { void _start() { exit(main()); } +void __start() { + exit(main()); +} diff --git a/sys.h b/sys.h index ee9a711..c2781bc 100644 --- a/sys.h +++ b/sys.h @@ -44,9 +44,9 @@ int bind(int sockfd, const void* sockaddr, socklen_t addrlen); int listen(int fd, int backlog); int accept(int sockfd, void* addr, socklen_t* addrlen); int connect(int sockfd, void* addr, socklen_t addrlen); -int64_t sendto(int sockfd, const void* buf, size_t size, int flags, const void* sockaddr, socklen_t addrlen); +ssize_t sendto(int sockfd, const void* buf, size_t size, int flags, const void* sockaddr, socklen_t addrlen); #define send(sockfd, buf, size, flags) sendto(sockfd, buf, size, flags, 0, 0) -int64_t recvfrom(int sockfd, const void* buf, size_t size, int flags, const void* sockaddr, socklen_t addrlen); +ssize_t recvfrom(int sockfd, const void* buf, size_t size, int flags, const void* sockaddr, socklen_t addrlen); #define recv(sockfd, buf, size, flags) recvfrom(sockfd, buf, size, flags, 0, 0) // Socket Domain constants typedef unsigned short sa_family_t; @@ -61,19 +61,46 @@ typedef unsigned short sa_family_t; #define AF_CAN 29 /* Controller Area Network */ #define AF_BLUETOOTH 31 /* Bluetooth sockets */ // Socket type constants -enum sock_type { -SOCK_STREAM = 1, -SOCK_DGRAM = 2, -SOCK_RAW = 3, -SOCK_RDM = 4, -SOCK_SEQPACKET = 5, -SOCK_DCCP = 6, -SOCK_PACKET = 10, -}; #if defined(__mips__) + // File: include/asm-mips/socket.h + enum sock_type { + SOCK_DGRAM = 1, + SOCK_STREAM = 2, + SOCK_RAW = 3, + SOCK_RDM = 4, + SOCK_SEQPACKET = 5, + SOCK_DCCP = 6, + SOCK_PACKET = 10, + }; #define SOL_SOCKET 0xffff + + #define SO_DEBUG 0x0001 /* Record debugging information. */ + #define SO_REUSEADDR 0x0004 /* Allow reuse of local addresses. */ + #define SO_TYPE 0x1008 /* Compatible name for SO_STYLE. */ + #define SO_ERROR 0x1007 /* get error status and clear */ + #define SO_DONTROUTE 0x0010 /* Don't do local routing. */ + #define SO_BROADCAST 0x0020 /* Allow transmission of broadcast messages. */ + #define SO_SNDBUF 0x1001 /* Send buffer size. */ + #define SO_RCVBUF 0x1002 /* Receive buffer. */ + #define SO_KEEPALIVE 0x0008 /* Keep connections alive and send SIGPIPE when they die. */ + #define SO_OOBINLINE 0x0100 /* Receive out-of-band data in-band. */ + #define SO_LINGER 0x0080 /* Block on close of a reliable socket to transmit pending data. */ + #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */ + #define SO_RCVLOWAT 0x1004 /* receive low-water mark */ + #define SO_SNDLOWAT 0x1003 /* send low-water mark */ + #define SO_RCVTIMEO 0x1006 /* receive timeout */ + #define SO_SNDTIMEO 0x1005 /* send timeout */ #else + enum sock_type { + SOCK_STREAM = 1, + SOCK_DGRAM = 2, + SOCK_RAW = 3, + SOCK_RDM = 4, + SOCK_SEQPACKET = 5, + SOCK_DCCP = 6, + SOCK_PACKET = 10, + }; #define SOL_SOCKET 1 #define SO_DEBUG 1