added 19 changesets to branch 'refs/remotes/jessicah-github/boot-syslog-ng' old head: 0000000000000000000000000000000000000000 new head: a9b6d1b5fd385686ca96b24fd86f9e234bf720fb overview: https://github.com/jessicah/haiku/compare/a9b6d1b ---------------------------------------------------------------------------- d08eefc: Don't double-free the Ethernet interface It is currently done in both ~EthernetService() and ~NetStack(). Since NetStack is where it's added and where an explicit accessor function is provided, choose that location. Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> [ Andreas Faerber <andreas.faerber@xxxxxx> ] cb9dcd2: Add net_stack_cleanup() Add a cleanup function net_stack_cleanup() that calls a new NetStack::ShutDown() method. Make sure this method works even if the network stack was never initialized. Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> [ Andreas Faerber <andreas.faerber@xxxxxx> ] 0884f5d: Detach UDP sockets on cleanup The UDP service does not own the UDP sockets. When shutting down, inform the bound sockets that the service is no longer available. This allows subsequent method calls to error out cleanly. Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> [ Andreas Faerber <andreas.faerber@xxxxxx> ] 0fbaaa5: Wire up net_stack_cleanup() The NetStack.h header is currently not usable from C code. So while net_stack_init() is called from platform code, we cannot call net_stack_cleanup() from OpenFirmware's platform_start_kernel(). Thus call it directly from main()'s cleanup TODO, having assured that the function is a no-op when no network stack was initialized. Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> [ Andreas Faerber <andreas.faerber@xxxxxx> ] e22c0be: EFI: move definition of EFI_IP_ADDRESS * This could have never worked previously due to cyclic dependencies * Also, IPv4, IPv6, and MAC address definitions were already in efidef.h [ Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ] 46d4a11: EFI: implement network driver using the simple network protocol [ Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ] 3996b7a: Add syslog-ng support Broadcast console output as syslog debug messages, stripped of trailing newlines. Disabled by default. Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> [ Andreas Faerber <andreas.faerber@xxxxxx> ] d423ac5: bootloader/efi: move net_stack_init to after console_init [ Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ] 8caf50a: Here begins a series of teeny commits, because I keep getting lost in a maze of inexplicable issues with no debug output to show the way... [ Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ] f6af9d4: So allocating the object fails, returning B_NO_MEMORY. Probably because the heap hasn't been initialised yet, so doing so in efi/start.cpp isn't effective. Perhaps it should be moved to main.cpp? [ Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ] 4385386: Use a static instance of NetStack; we can't allocate objects on the heap just yet... ironically, the whole setup currently uses a singleton pattern anyway, so should clean this up to do it without needing to allocate on the heap. [ Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ] 1285f12: a bit more promising... init efi driver failed :) [ Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ] a3fd13b: Well, it doesn't crash, but it doesn't work either. Getting EFI_DEVICE_ERROR in the Initialize() call. [ Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ] bfba500: Got a MAC address! \o/ [ Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ] 297611b: Just need to slowly move the #if 0 down, see where it finally dies. Getting very close to a working syslog over udp... [ Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ] 6520496: Bootloader: add some more shortcuts to the menu items [ Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ] a19fcc6: In theory, should have a functional EFI network stack... but I don't seem to be receiving any packets from my test box. [ Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ] e5d9223: Replace arch-dependent integer byteswap routines with gcc builtins [ Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ] a9b6d1b: Dirty commit of stuff before destroying my VM :p [ Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ] ---------------------------------------------------------------------------- 21 files changed, 443 insertions(+), 69 deletions(-) headers/os/support/ByteOrder.h | 35 ++-- headers/private/app/MessageUtils.h | 12 +- headers/private/kernel/boot/net/NetStack.h | 7 +- headers/private/kernel/boot/net/UDP.h | 1 + headers/private/kernel/boot/platform.h | 1 + .../private/kernel/boot/platform/efi/efidef.h | 10 ++ .../private/kernel/boot/platform/efi/efipxebc.h | 9 - src/kits/app/MessageAdapter.cpp | 6 +- src/kits/support/ByteOrder.cpp | 12 +- src/system/boot/arch/x86/Jamfile | 2 +- .../loader/file_systems/packagefs/packagefs.cpp | 1 + src/system/boot/loader/main.cpp | 4 + src/system/boot/loader/menu.cpp | 4 + src/system/boot/loader/net/Ethernet.cpp | 2 - src/system/boot/loader/net/NetStack.cpp | 70 ++++++-- src/system/boot/loader/net/UDP.cpp | 15 ++ src/system/boot/loader/stdio.cpp | 63 ++++++- src/system/boot/platform/efi/Jamfile | 1 + src/system/boot/platform/efi/debug.cpp | 75 +++++++- src/system/boot/platform/efi/netstack.cpp | 178 +++++++++++++++++++ src/system/boot/platform/efi/start.cpp | 4 + ############################################################################ Commit: d08eefcefba0cdf4bdad091a2a88a1e2d4b85551 Author: Andreas Faerber <andreas.faerber@xxxxxx> Date: Sun Jun 13 14:44:09 2010 UTC Committer: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Commit-Date: Sun Apr 27 09:07:25 2014 UTC Don't double-free the Ethernet interface It is currently done in both ~EthernetService() and ~NetStack(). Since NetStack is where it's added and where an explicit accessor function is provided, choose that location. Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ---------------------------------------------------------------------------- diff --git a/src/system/boot/loader/net/Ethernet.cpp b/src/system/boot/loader/net/Ethernet.cpp index 6e16756..e2724bc 100644 --- a/src/system/boot/loader/net/Ethernet.cpp +++ b/src/system/boot/loader/net/Ethernet.cpp @@ -77,8 +77,6 @@ EthernetService::~EthernetService() { if (fSendBuffer) fInterface->FreeSendReceiveBuffer(fSendBuffer); - - delete fInterface; } // Init ############################################################################ Commit: cb9dcd2ed7850f728db2fc194e99bc4c66656664 Author: Andreas Faerber <andreas.faerber@xxxxxx> Date: Sun Jun 13 14:55:53 2010 UTC Committer: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Commit-Date: Sun Apr 27 09:07:25 2014 UTC Add net_stack_cleanup() Add a cleanup function net_stack_cleanup() that calls a new NetStack::ShutDown() method. Make sure this method works even if the network stack was never initialized. Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ---------------------------------------------------------------------------- diff --git a/headers/private/kernel/boot/net/NetStack.h b/headers/private/kernel/boot/net/NetStack.h index f148732..5092d6e 100644 --- a/headers/private/kernel/boot/net/NetStack.h +++ b/headers/private/kernel/boot/net/NetStack.h @@ -26,6 +26,7 @@ private: public: static status_t CreateDefault(); static NetStack *Default(); + static status_t ShutDown(); status_t AddEthernetInterface(EthernetInterface *interface); @@ -53,6 +54,7 @@ private: // afterwards, which is supposed to add network interfaces. status_t net_stack_init(); status_t platform_net_stack_init(); +status_t net_stack_cleanup(); #endif // _BOOT_NET_STACK_H diff --git a/src/system/boot/loader/net/NetStack.cpp b/src/system/boot/loader/net/NetStack.cpp index 52b3543..d456a26 100644 --- a/src/system/boot/loader/net/NetStack.cpp +++ b/src/system/boot/loader/net/NetStack.cpp @@ -117,6 +117,19 @@ NetStack::Default() return sNetStack; } + +status_t +NetStack::ShutDown() +{ + if (sNetStack != NULL) { + delete sNetStack; + sNetStack = NULL; + } + + return B_OK; +} + + // AddEthernetInterface status_t NetStack::AddEthernetInterface(EthernetInterface *interface) @@ -152,3 +165,9 @@ net_stack_init() return platform_net_stack_init(); } + +status_t +net_stack_cleanup() +{ + return NetStack::ShutDown(); +} ############################################################################ Commit: 0884f5df5da58113d7ee4c466bb6a6996dd9b6dc Author: Andreas Faerber <andreas.faerber@xxxxxx> Date: Sun Jun 13 15:50:11 2010 UTC Committer: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Commit-Date: Sun Apr 27 09:07:26 2014 UTC Detach UDP sockets on cleanup The UDP service does not own the UDP sockets. When shutting down, inform the bound sockets that the service is no longer available. This allows subsequent method calls to error out cleanly. Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ---------------------------------------------------------------------------- diff --git a/headers/private/kernel/boot/net/UDP.h b/headers/private/kernel/boot/net/UDP.h index fd1bdd6..2b587f4 100644 --- a/headers/private/kernel/boot/net/UDP.h +++ b/headers/private/kernel/boot/net/UDP.h @@ -52,6 +52,7 @@ public: uint16 Port() const { return fPort; } status_t Bind(ip_addr_t address, uint16 port); + void Detach(); status_t Send(ip_addr_t destinationAddress, uint16 destinationPort, ChainBuffer *buffer); diff --git a/src/system/boot/loader/net/UDP.cpp b/src/system/boot/loader/net/UDP.cpp index 205ddc6..2679953 100644 --- a/src/system/boot/loader/net/UDP.cpp +++ b/src/system/boot/loader/net/UDP.cpp @@ -172,6 +172,15 @@ UDPSocket::Bind(ip_addr_t address, uint16 port) } +void +UDPSocket::Detach() +{ + fUDPService = NULL; + // This will lead to subsequent methods returning B_NO_INIT +} + + + status_t UDPSocket::Send(ip_addr_t destinationAddress, uint16 destinationPort, ChainBuffer *buffer) @@ -261,6 +270,12 @@ UDPService::UDPService(IPService *ipService) UDPService::~UDPService() { + int count = fSockets.Count(); + for (int i = 0; i < count; i++) { + UDPSocket *socket = fSockets.ElementAt(i); + socket->Detach(); + } + if (fIPService != NULL) fIPService->UnregisterIPSubService(this); } ############################################################################ Commit: 0fbaaa5e140a56a9adc57c20460481e1c205062c Author: Andreas Faerber <andreas.faerber@xxxxxx> Date: Sun Jun 13 15:00:45 2010 UTC Committer: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Commit-Date: Sun Apr 27 09:07:26 2014 UTC Wire up net_stack_cleanup() The NetStack.h header is currently not usable from C code. So while net_stack_init() is called from platform code, we cannot call net_stack_cleanup() from OpenFirmware's platform_start_kernel(). Thus call it directly from main()'s cleanup TODO, having assured that the function is a no-op when no network stack was initialized. Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ---------------------------------------------------------------------------- diff --git a/src/system/boot/loader/main.cpp b/src/system/boot/loader/main.cpp index e0555dcd..ea94c1a 100644 --- a/src/system/boot/loader/main.cpp +++ b/src/system/boot/loader/main.cpp @@ -14,6 +14,7 @@ #include <boot/heap.h> #include <boot/PathBlacklist.h> #include <boot/stdio.h> +#include <boot/net/NetStack.h> #include "file_systems/packagefs/packagefs.h" @@ -142,6 +143,7 @@ main(stage2_args *args) gKernelArgs.boot_volume = buffer; gKernelArgs.boot_volume_size = gBootVolume.ContentSize(); + net_stack_cleanup(); // ToDo: cleanup, heap_release() etc. heap_print_statistics(); platform_start_kernel(); ############################################################################ Commit: e22c0be0c3513bb9da3206fe3efd1a2277f57217 Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Sun Apr 27 10:52:09 2014 UTC EFI: move definition of EFI_IP_ADDRESS * This could have never worked previously due to cyclic dependencies * Also, IPv4, IPv6, and MAC address definitions were already in efidef.h ---------------------------------------------------------------------------- diff --git a/headers/private/kernel/boot/platform/efi/efidef.h b/headers/private/kernel/boot/platform/efi/efidef.h index 18032c8..5ec48aa 100644 --- a/headers/private/kernel/boot/platform/efi/efidef.h +++ b/headers/private/kernel/boot/platform/efi/efidef.h @@ -111,6 +111,16 @@ typedef struct { UINT8 Addr[32]; } EFI_MAC_ADDRESS; +// +// Address definitions +// + +typedef union { + UINT32 Addr[4]; + EFI_IPv4_ADDRESS v4; + EFI_IPv6_ADDRESS v6; +} EFI_IP_ADDRESS; + typedef struct { UINT32 ReceivedQueueTimeoutValue; UINT32 TransmitQueueTimeoutValue; diff --git a/headers/private/kernel/boot/platform/efi/efipxebc.h b/headers/private/kernel/boot/platform/efi/efipxebc.h index d5601d9..e33ce89 100644 --- a/headers/private/kernel/boot/platform/efi/efipxebc.h +++ b/headers/private/kernel/boot/platform/efi/efipxebc.h @@ -30,15 +30,6 @@ INTERFACE_DECL(_EFI_PXE_BASE_CODE); #define DEFAULT_TTL 4 #define DEFAULT_ToS 0 -// -// Address definitions -// - -typedef union { - UINT32 Addr[4]; - EFI_IPv4_ADDRESS v4; - EFI_IPv6_ADDRESS v6; -} EFI_IP_ADDRESS; typedef UINT16 EFI_PXE_BASE_CODE_UDP_PORT; ############################################################################ Commit: 46d4a1194221de0329a16be633550d973d6b675f Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Sun Apr 27 11:59:14 2014 UTC EFI: implement network driver using the simple network protocol ---------------------------------------------------------------------------- diff --git a/src/system/boot/platform/efi/Jamfile b/src/system/boot/platform/efi/Jamfile index 3a9e241..d179f3f 100644 --- a/src/system/boot/platform/efi/Jamfile +++ b/src/system/boot/platform/efi/Jamfile @@ -20,6 +20,7 @@ local efi_glue_src = BootMergeObject boot_platform_efi.o : console.cpp debug.cpp + netstack.cpp devices.cpp start.cpp video.cpp diff --git a/src/system/boot/platform/efi/netstack.cpp b/src/system/boot/platform/efi/netstack.cpp new file mode 100644 index 0000000..d5633b5 --- /dev/null +++ b/src/system/boot/platform/efi/netstack.cpp @@ -0,0 +1,161 @@ +/* + * Copyright 2014, Jessica Hamilton, jessica.l.hamilton@xxxxxxxxx. + * Distributed under the terms of the MIT License. + */ + + +#include "efi_platform.h" +#include "efinet.h" + +#include <boot/net/NetStack.h> +#include <boot/net/Ethernet.h> + +#include <time.h> + +static EFI_GUID sSimpleNetworkGuid = EFI_SIMPLE_NETWORK_PROTOCOL; + + +class EFIEthernetInterface : public EthernetInterface { +public: + EFIEthernetInterface(); + virtual ~EFIEthernetInterface(); + + status_t Init(); + + virtual mac_addr_t MACAddress() const; + + virtual void *AllocateSendReceiveBuffer(size_t size); + virtual void FreeSendReceiveBuffer(void *buffer); + + virtual ssize_t Send(const void *buffer, size_t size); + virtual ssize_t Receive(void *buffer, size_t size); + +private: + EFI_SIMPLE_NETWORK *fNetwork; + mac_addr_t fMACAddress; +}; + + +EFIEthernetInterface::EFIEthernetInterface() + : + EthernetInterface(), + fNetwork(NULL), + fMACAddress(kNoMACAddress) +{ +} + + +EFIEthernetInterface::~EFIEthernetInterface() +{ + if (fNetwork != NULL) { + fNetwork->Shutdown(fNetwork); + fNetwork->Stop(fNetwork); + fNetwork = NULL; + } +} + + +status_t +EFIEthernetInterface::Init() +{ + EFI_STATUS status = kBootServices->LocateProtocol(&sSimpleNetworkGuid, + NULL, (void **)&fNetwork); + + if (status != EFI_SUCCESS || fNetwork == NULL) + return B_ERROR; + + if (fNetwork->Start(fNetwork) != EFI_SUCCESS) + return B_ERROR; + if (fNetwork->Initialize(fNetwork, 0, 0) != EFI_SUCCESS) + return B_ERROR; + + // get MAC address + EFI_MAC_ADDRESS macAddress = fNetwork->Mode->CurrentAddress; + //ASSERT(fNetwork->Mode->HwAddressSize == ETH_ALEN); + fMACAddress = macAddress.Addr; + + return B_OK; +} + + +mac_addr_t +EFIEthernetInterface::MACAddress() const +{ + return fMACAddress; +} + + +void * +EFIEthernetInterface::AllocateSendReceiveBuffer(size_t size) +{ + return malloc(size); +} + + +void +EFIEthernetInterface::FreeSendReceiveBuffer(void *buffer) +{ + if (buffer != NULL) + free(buffer); +} + + +ssize_t +EFIEthernetInterface::Send(const void *buffer, size_t size) +{ + EFI_STATUS status = fNetwork->Transmit(fNetwork, 0, size, (void *)buffer, NULL, NULL, NULL); + + if (status == EFI_SUCCESS) { + // Need to wait for packet to be transmitted so we can recyle the transmit buffer + void *txBuffer; + do { + if (fNetwork->GetStatus(fNetwork, NULL, &txBuffer) != EFI_SUCCESS) + return B_ERROR; + + struct timespec ts; + ts.tv_sec = 0; + ts.tv_nsec = 50 * 1000; + nanosleep(&ts, NULL); + } while (txBuffer != buffer); + } + + return size; +} + + +ssize_t +EFIEthernetInterface::Receive(void *buffer, size_t size) +{ + EFI_STATUS status = fNetwork->Receive(fNetwork, NULL, &size, buffer, NULL, NULL, NULL); + + if (status == EFI_NOT_READY) + return 0; + + if (status != EFI_SUCCESS) + return B_ERROR; + + return size; +} + + +status_t +platform_net_stack_init() +{ + EFIEthernetInterface *interface = new(std::nothrow) EFIEthernetInterface; + if (!interface) + return B_NO_MEMORY; + + status_t error = interface->Init(); + if (error != B_OK) { + delete interface; + return error; + } + + error = NetStack::Default()->AddEthernetInterface(interface); + if (error != B_OK) { + delete interface; + return error; + } + + return B_OK; +} diff --git a/src/system/boot/platform/efi/start.cpp b/src/system/boot/platform/efi/start.cpp index 4d3040c..4a47cfb 100644 --- a/src/system/boot/platform/efi/start.cpp +++ b/src/system/boot/platform/efi/start.cpp @@ -13,6 +13,7 @@ #include <boot/platform.h> #include <boot/heap.h> #include <boot/stage2.h> +#include <boot/net/NetStack.h> //#include "acpi.h" //#include "apm.h" @@ -106,6 +107,7 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systemTable) serial_init(); serial_enable(); + net_stack_init(); // interrupts_init(); console_init(); // cpu_init(); ############################################################################ Commit: 3996b7a9b48caf950963f3cd34fd3d3d88675e81 Author: Andreas Faerber <andreas.faerber@xxxxxx> Date: Sun Jun 13 20:17:40 2010 UTC Committer: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Commit-Date: Sun Apr 27 12:08:43 2014 UTC Add syslog-ng support Broadcast console output as syslog debug messages, stripped of trailing newlines. Disabled by default. Signed-off-by: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> ---------------------------------------------------------------------------- diff --git a/src/system/boot/loader/stdio.cpp b/src/system/boot/loader/stdio.cpp index 267ddbd..34f9c7f 100644 --- a/src/system/boot/loader/stdio.cpp +++ b/src/system/boot/loader/stdio.cpp @@ -6,6 +6,8 @@ #include <boot/vfs.h> #include <boot/stdio.h> +#include <boot/net/NetStack.h> +#include <boot/net/UDP.h> #include <errno.h> #include <stdarg.h> @@ -20,6 +22,9 @@ //extern FILE *stdin; +//#define ENABLE_SYSLOG + + #undef errno int errno; @@ -31,6 +36,50 @@ _errnop(void) } +#ifdef ENABLE_SYSLOG + +static UDPSocket *sSyslogSocket = NULL; + +static void +sendToSyslog(const char *message, int length) +{ + // Lazy-initialize the socket + if (sSyslogSocket == NULL) { + // Check if the network stack has been initialized yet + if (NetStack::Default() != NULL) { + sSyslogSocket = new(std::nothrow) UDPSocket; + sSyslogSocket->Bind(INADDR_ANY, 60514); + } + } + + if (sSyslogSocket == NULL) + return; + + // Strip trailing newlines + while (length > 0) { + if (message[length - 1] != '\n' + && message[length - 1] != '\r') { + break; + } + length--; + } + if (length <= 0) + return; + + char buffer[1500]; + // same comment as in vfprintf applies... + const int facility = 0; // kernel + int severity = 7; // debug + int offset = snprintf(buffer, sizeof(buffer), "<%d>1 - - Haiku - - - \xEF\xBB\xBF", + facility * 8 + severity); + length = std::min(length, (int)sizeof(buffer) - offset); + memcpy(buffer + offset, message, length); + sSyslogSocket->Send(INADDR_BROADCAST, 514, buffer, offset + length); +} + +#endif + + int vfprintf(FILE *file, const char *format, va_list list) { @@ -40,8 +89,12 @@ vfprintf(FILE *file, const char *format, va_list list) int length = vsnprintf(buffer, sizeof(buffer), format, list); length = std::min(length, (int)sizeof(buffer) - 1); - if (length > 0) + if (length > 0) { node->Write(buffer, length); +#ifdef ENABLE_SYSLOG + sendToSyslog(buffer, length); +#endif + } return length; } @@ -92,6 +145,10 @@ fputc(int c, FILE *file) // we only support direct console output right now... status = ((ConsoleNode *)file)->Write(&character, 1); +#ifdef ENABLE_SYSLOG + sendToSyslog(&character, 1); +#endif + if (status > 0) return character; @@ -108,6 +165,10 @@ fputs(const char *string, FILE *file) status_t status = ((ConsoleNode *)file)->Write(string, strlen(string)); fputc('\n', file); +#ifdef ENABLE_SYSLOG + sendToSyslog(string, strlen(string)); +#endif + return status; } ############################################################################ Commit: d423ac5310a0ff89547dffa5cac6fd95815c5c48 Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Mon Apr 28 10:05:53 2014 UTC bootloader/efi: move net_stack_init to after console_init ---------------------------------------------------------------------------- diff --git a/src/system/boot/platform/efi/start.cpp b/src/system/boot/platform/efi/start.cpp index 4a47cfb..c5098e4 100644 --- a/src/system/boot/platform/efi/start.cpp +++ b/src/system/boot/platform/efi/start.cpp @@ -107,9 +107,9 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systemTable) serial_init(); serial_enable(); - net_stack_init(); // interrupts_init(); console_init(); + net_stack_init(); // cpu_init(); // mmu_init(); debug_init_post_mmu(); ############################################################################ Commit: 8caf50a0673da1b8e19235e47713e6b200390d0d Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Mon Apr 28 10:36:48 2014 UTC Here begins a series of teeny commits, because I keep getting lost in a maze of inexplicable issues with no debug output to show the way... ---------------------------------------------------------------------------- diff --git a/src/system/boot/loader/net/NetStack.cpp b/src/system/boot/loader/net/NetStack.cpp index d456a26..baaa223 100644 --- a/src/system/boot/loader/net/NetStack.cpp +++ b/src/system/boot/loader/net/NetStack.cpp @@ -15,6 +15,11 @@ #include <boot/net/UDP.h> #include <boot/net/TCP.h> +#include <KernelExport.h> + + +#define MSG(format, args...) \ + dprintf("%s:%d: " format "\n", __FILE__, __LINE__ , ## args) // sNetStack NetStack *NetStack::sNetStack = NULL; @@ -158,6 +163,7 @@ NetStack::AddEthernetInterface(EthernetInterface *interface) status_t net_stack_init() { + MSG("enter"); status_t error = NetStack::CreateDefault(); if (error != B_OK) return error; ############################################################################ Commit: f6af9d47bd738f94b52e00d6fc84a149e2be52c8 Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Mon Apr 28 11:12:31 2014 UTC So allocating the object fails, returning B_NO_MEMORY. Probably because the heap hasn't been initialised yet, so doing so in efi/start.cpp isn't effective. Perhaps it should be moved to main.cpp? ---------------------------------------------------------------------------- diff --git a/src/system/boot/loader/net/NetStack.cpp b/src/system/boot/loader/net/NetStack.cpp index baaa223..b8449e3 100644 --- a/src/system/boot/loader/net/NetStack.cpp +++ b/src/system/boot/loader/net/NetStack.cpp @@ -102,6 +102,7 @@ NetStack::CreateDefault() return B_OK; NetStack *netStack = new(nothrow) NetStack; + MSG("netStack = %p", netStack); if (!netStack) return B_NO_MEMORY; @@ -165,8 +166,11 @@ net_stack_init() { MSG("enter"); status_t error = NetStack::CreateDefault(); - if (error != B_OK) + if (error != B_OK) { + MSG("create default: %lx", error); return error; + } + MSG("created"); return platform_net_stack_init(); } diff --git a/src/system/boot/platform/efi/start.cpp b/src/system/boot/platform/efi/start.cpp index c5098e4..6caa3f4 100644 --- a/src/system/boot/platform/efi/start.cpp +++ b/src/system/boot/platform/efi/start.cpp @@ -109,7 +109,9 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systemTable) serial_enable(); // interrupts_init(); console_init(); - net_stack_init(); +// net_stack_init(); +// we can't actually init the network stack here... as we can't allocate +// objects yet... // cpu_init(); // mmu_init(); debug_init_post_mmu(); ############################################################################ Commit: 4385386035204c98e71bd2a8191d7723c75cdd93 Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Mon Apr 28 11:53:50 2014 UTC Use a static instance of NetStack; we can't allocate objects on the heap just yet... ironically, the whole setup currently uses a singleton pattern anyway, so should clean this up to do it without needing to allocate on the heap. ---------------------------------------------------------------------------- diff --git a/headers/private/kernel/boot/net/NetStack.h b/headers/private/kernel/boot/net/NetStack.h index 5092d6e..f3e7c17 100644 --- a/headers/private/kernel/boot/net/NetStack.h +++ b/headers/private/kernel/boot/net/NetStack.h @@ -17,7 +17,7 @@ class TCPService; class NetStack { -private: +public: NetStack(); ~NetStack(); diff --git a/src/system/boot/loader/net/NetStack.cpp b/src/system/boot/loader/net/NetStack.cpp index b8449e3..e0c77a6 100644 --- a/src/system/boot/loader/net/NetStack.cpp +++ b/src/system/boot/loader/net/NetStack.cpp @@ -5,10 +5,6 @@ #include <boot/net/NetStack.h> -#include <new> - -#include <stdio.h> - #include <boot/net/ARP.h> #include <boot/net/Ethernet.h> #include <boot/net/IP.h> @@ -24,6 +20,8 @@ // sNetStack NetStack *NetStack::sNetStack = NULL; +static NetStack sStaticNetStack; + // constructor NetStack::NetStack() : fEthernetInterface(NULL), @@ -94,25 +92,12 @@ NetStack::Init() return B_OK; } +static bool created = false; + // CreateDefault status_t NetStack::CreateDefault() { - if (sNetStack) - return B_OK; - - NetStack *netStack = new(nothrow) NetStack; - MSG("netStack = %p", netStack); - if (!netStack) - return B_NO_MEMORY; - - status_t error = netStack->Init(); - if (error != B_OK) { - delete netStack; - return error; - } - - sNetStack = netStack; return B_OK; } @@ -120,6 +105,13 @@ NetStack::CreateDefault() NetStack * NetStack::Default() { + if (created == false) { + if (sStaticNetStack.Init() != B_OK) { + return NULL; + } + sNetStack = &sStaticNetStack; + created = true; + } return sNetStack; } @@ -167,7 +159,7 @@ net_stack_init() MSG("enter"); status_t error = NetStack::CreateDefault(); if (error != B_OK) { - MSG("create default: %lx", error); + MSG("create default: %x", error); return error; } MSG("created"); diff --git a/src/system/boot/platform/efi/netstack.cpp b/src/system/boot/platform/efi/netstack.cpp index d5633b5..458d12e 100644 --- a/src/system/boot/platform/efi/netstack.cpp +++ b/src/system/boot/platform/efi/netstack.cpp @@ -141,6 +141,9 @@ EFIEthernetInterface::Receive(void *buffer, size_t size) status_t platform_net_stack_init() { + if (NetStack::Default() == NULL) + return B_NO_MEMORY; + EFIEthernetInterface *interface = new(std::nothrow) EFIEthernetInterface; if (!interface) return B_NO_MEMORY; diff --git a/src/system/boot/platform/efi/start.cpp b/src/system/boot/platform/efi/start.cpp index 6caa3f4..66bd8ab 100644 --- a/src/system/boot/platform/efi/start.cpp +++ b/src/system/boot/platform/efi/start.cpp @@ -109,9 +109,9 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systemTable) serial_enable(); // interrupts_init(); console_init(); -// net_stack_init(); + net_stack_init(); // we can't actually init the network stack here... as we can't allocate -// objects yet... +// objects yet... can we? we can initialise static objects... // cpu_init(); // mmu_init(); debug_init_post_mmu(); ############################################################################ Commit: 1285f12fb398f3750944cae9eeb789e6147a5e5a Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Mon Apr 28 12:10:20 2014 UTC a bit more promising... init efi driver failed :) ---------------------------------------------------------------------------- diff --git a/src/system/boot/loader/main.cpp b/src/system/boot/loader/main.cpp index ea94c1a..0301091 100644 --- a/src/system/boot/loader/main.cpp +++ b/src/system/boot/loader/main.cpp @@ -44,6 +44,8 @@ main(stage2_args *args) // used as a boolean indicator until initialized for the kernel #endif + platform_net_stack_init(); + add_stage2_driver_settings(args); platform_init_video(); diff --git a/src/system/boot/loader/net/NetStack.cpp b/src/system/boot/loader/net/NetStack.cpp index e0c77a6..24c3c47 100644 --- a/src/system/boot/loader/net/NetStack.cpp +++ b/src/system/boot/loader/net/NetStack.cpp @@ -164,7 +164,8 @@ net_stack_init() } MSG("created"); - return platform_net_stack_init(); + //return platform_net_stack_init(); + // don't do this here for now } diff --git a/src/system/boot/platform/efi/netstack.cpp b/src/system/boot/platform/efi/netstack.cpp index 458d12e..513d5ad 100644 --- a/src/system/boot/platform/efi/netstack.cpp +++ b/src/system/boot/platform/efi/netstack.cpp @@ -10,6 +10,8 @@ #include <boot/net/NetStack.h> #include <boot/net/Ethernet.h> +#include <KernelExport.h> + #include <time.h> static EFI_GUID sSimpleNetworkGuid = EFI_SIMPLE_NETWORK_PROTOCOL; @@ -137,28 +139,38 @@ EFIEthernetInterface::Receive(void *buffer, size_t size) return size; } +#define MSG(format, args...) \ + dprintf("%s:%d: " format "\n", __FILE__, __LINE__ , ## args) status_t platform_net_stack_init() { - if (NetStack::Default() == NULL) + MSG("enter"); + if (NetStack::Default() == NULL) { + MSG("no memory for default netstack"); return B_NO_MEMORY; + } EFIEthernetInterface *interface = new(std::nothrow) EFIEthernetInterface; - if (!interface) + if (!interface) { + MSG("no memory for efi driver"); return B_NO_MEMORY; + } status_t error = interface->Init(); if (error != B_OK) { + MSG("init efi driver failed"); delete interface; return error; } error = NetStack::Default()->AddEthernetInterface(interface); if (error != B_OK) { + MSG("add efi driver to netstack failed"); delete interface; return error; } + MSG("exit"); return B_OK; } ############################################################################ Commit: a3fd13b77fd805ace118effa04b4981790015a20 Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Mon Apr 28 12:34:34 2014 UTC Well, it doesn't crash, but it doesn't work either. Getting EFI_DEVICE_ERROR in the Initialize() call. ---------------------------------------------------------------------------- diff --git a/src/system/boot/platform/efi/netstack.cpp b/src/system/boot/platform/efi/netstack.cpp index 513d5ad..2611ece 100644 --- a/src/system/boot/platform/efi/netstack.cpp +++ b/src/system/boot/platform/efi/netstack.cpp @@ -14,6 +14,11 @@ #include <time.h> + +#define MSG(format, args...) \ + dprintf("%s:%d: " format "\n", __FILE__, __LINE__ , ## args) + + static EFI_GUID sSimpleNetworkGuid = EFI_SIMPLE_NETWORK_PROTOCOL; @@ -63,19 +68,29 @@ EFIEthernetInterface::Init() EFI_STATUS status = kBootServices->LocateProtocol(&sSimpleNetworkGuid, NULL, (void **)&fNetwork); - if (status != EFI_SUCCESS || fNetwork == NULL) + if (status != EFI_SUCCESS || fNetwork == NULL) { + MSG("locate protocol failed: %x (%p)", status, fNetwork); return B_ERROR; + } - if (fNetwork->Start(fNetwork) != EFI_SUCCESS) + status = fNetwork->Start(fNetwork); + if (status != EFI_SUCCESS && status != EFI_ALREADY_STARTED) { + MSG("failed to start simple network protocol: %x", status); return B_ERROR; - if (fNetwork->Initialize(fNetwork, 0, 0) != EFI_SUCCESS) + } + status = fNetwork->Initialize(fNetwork, 0x1000, 0x1000); + if (status != EFI_SUCCESS) { + MSG("failed to initialize simple network protocol: %x", status); return B_ERROR; + } // get MAC address EFI_MAC_ADDRESS macAddress = fNetwork->Mode->CurrentAddress; //ASSERT(fNetwork->Mode->HwAddressSize == ETH_ALEN); + #define AT(i) fMACAddress[i] fMACAddress = macAddress.Addr; - + MSG("mac address: %2x:%2x:%2x:%2x:%2x:%2x", AT(0), AT(1), AT(2), AT(3), AT(4), AT(5)); + #undef AT return B_OK; } @@ -139,9 +154,6 @@ EFIEthernetInterface::Receive(void *buffer, size_t size) return size; } -#define MSG(format, args...) \ - dprintf("%s:%d: " format "\n", __FILE__, __LINE__ , ## args) - status_t platform_net_stack_init() { ############################################################################ Commit: bfba500c8e30f93c01142b0e24335a15bc3c0423 Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Mon Apr 28 12:40:05 2014 UTC Got a MAC address! \o/ ---------------------------------------------------------------------------- diff --git a/src/system/boot/platform/efi/netstack.cpp b/src/system/boot/platform/efi/netstack.cpp index 2611ece..f5dc4db 100644 --- a/src/system/boot/platform/efi/netstack.cpp +++ b/src/system/boot/platform/efi/netstack.cpp @@ -73,6 +73,9 @@ EFIEthernetInterface::Init() return B_ERROR; } + status = fNetwork->Shutdown(fNetwork); + MSG("shutting down first, so can start from scratch... %x", status); + status = fNetwork->Start(fNetwork); if (status != EFI_SUCCESS && status != EFI_ALREADY_STARTED) { MSG("failed to start simple network protocol: %x", status); ############################################################################ Commit: 297611b8feab9f27a9d9ac48acbfdf92c3e09a32 Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Mon Apr 28 13:12:55 2014 UTC Just need to slowly move the #if 0 down, see where it finally dies. Getting very close to a working syslog over udp... ---------------------------------------------------------------------------- diff --git a/headers/private/kernel/boot/net/NetStack.h b/headers/private/kernel/boot/net/NetStack.h index f3e7c17..cc0ae4f 100644 --- a/headers/private/kernel/boot/net/NetStack.h +++ b/headers/private/kernel/boot/net/NetStack.h @@ -27,7 +27,7 @@ public: static status_t CreateDefault(); static NetStack *Default(); static status_t ShutDown(); - + static status_t InitCheck(); status_t AddEthernetInterface(EthernetInterface *interface); EthernetInterface *GetEthernetInterface() const diff --git a/src/system/boot/loader/net/NetStack.cpp b/src/system/boot/loader/net/NetStack.cpp index 24c3c47..93b4418 100644 --- a/src/system/boot/loader/net/NetStack.cpp +++ b/src/system/boot/loader/net/NetStack.cpp @@ -115,6 +115,12 @@ NetStack::Default() return sNetStack; } +status_t +NetStack::InitCheck() +{ + return created == true ? B_OK : B_NO_INIT; +} + status_t NetStack::ShutDown() diff --git a/src/system/boot/platform/efi/debug.cpp b/src/system/boot/platform/efi/debug.cpp index 5e95aba..e64bd1f 100644 --- a/src/system/boot/platform/efi/debug.cpp +++ b/src/system/boot/platform/efi/debug.cpp @@ -11,15 +11,21 @@ #include <boot/platform.h> #include <boot/stage2.h> #include <boot/stdio.h> +#include <boot/net/NetStack.h> +#include <boot/net/UDP.h> #include <kernel.h> #include <util/ring_buffer.h> +#include <algorithm> + #include "keyboard.h" #include "serial.h" //#define PRINT_TIME_STAMPS // Define to print a TSC timestamp before each line of output. +#define ENABLE_SYSLOG_NG + // Define to print syslog messages over UDP. static const char* const kDebugSyslogSignature = "Haiku syslog"; @@ -36,6 +42,49 @@ extern "C" uint64 rdtsc(); #endif +#ifdef ENABLE_SYSLOG_NG +static UDPSocket *sSyslogSocket = NULL; + +static void +syslog_ng_write(const char *message, size_t length) +{ + if (NetStack::InitCheck() == B_NO_INIT) + return; +#if 0 + if (sSyslogSocket == NULL) { + // Check if the network stack has been initialized yet + if (NetStack::Default() != NULL) { + sSyslogSocket = new(std::nothrow) UDPSocket; + if (sSyslogSocket == NULL) + return; + sSyslogSocket->Bind(INADDR_ANY, 60514); + } + } + + // Strip trailing newlines + while (length > 0) { + if (message[length - 1] != '\n' + && message[length - 1] != '\r') { + break; + } + length--; + } + if (length <= 0) + return; + + char buffer[1500]; + const int facility = 0; // kernel + int severity = 7; // debug + int offset = snprintf(buffer, sizeof(buffer), "<%d>1 - - Haiku - - - \xEF\xBB\xBF", + facility * 8 + severity); + length = std::min(length, sizeof(buffer) - offset); + memcpy(buffer + offset, message, length); + sSyslogSocket->Send(INADDR_BROADCAST, 514, buffer, offset + length); +#endif +} +#endif + + static void syslog_write(const char* buffer, size_t length) { @@ -74,6 +123,9 @@ dprintf_args(const char *format, va_list args) syslog_write(buffer, length); serial_puts(buffer, length); +#ifdef ENABLE_SYSLOG_NG + syslog_ng_write(buffer, length); +#endif if (platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT) fprintf(stderr, "%s", buffer); ############################################################################ Commit: 652049654627311d6c910c8a6bf10fdefb77cc07 Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Tue Apr 29 10:10:49 2014 UTC Bootloader: add some more shortcuts to the menu items ---------------------------------------------------------------------------- diff --git a/src/system/boot/loader/menu.cpp b/src/system/boot/loader/menu.cpp index 9f91397..a6d6e85 100644 --- a/src/system/boot/loader/menu.cpp +++ b/src/system/boot/loader/menu.cpp @@ -1311,6 +1311,7 @@ add_debug_menu() item->SetType(MENU_ITEM_NO_CHOICE); item->SetHelpText( "Displays the debug info the boot loader has logged."); + item->SetShortcut('l'); } if (hasPreviousSyslog) { @@ -1416,14 +1417,17 @@ user_menu(BootVolume& _bootVolume, PathBlacklist& _pathBlacklist) // Add boot volume menu->AddItem(item = new(std::nothrow) MenuItem("Select boot volume", add_boot_volume_menu(_bootVolume.RootDirectory()))); + item->SetShortcut('v'); // Add safe mode menu->AddItem(item = new(std::nothrow) MenuItem("Select safe mode options", safeModeMenu = add_safe_mode_menu())); + item->SetShortcut('s'); // add debug menu menu->AddItem(item = new(std::nothrow) MenuItem("Select debug options", debugMenu = add_debug_menu())); + item->SetShortcut('d'); // Add platform dependent menus platform_add_menus(menu); ############################################################################ Commit: a19fcc63383be55e378ed45d4f6d09db4571c134 Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Tue Apr 29 10:18:32 2014 UTC In theory, should have a functional EFI network stack... but I don't seem to be receiving any packets from my test box. ---------------------------------------------------------------------------- diff --git a/src/system/boot/loader/net/NetStack.cpp b/src/system/boot/loader/net/NetStack.cpp index 93b4418..03bc995 100644 --- a/src/system/boot/loader/net/NetStack.cpp +++ b/src/system/boot/loader/net/NetStack.cpp @@ -118,7 +118,9 @@ NetStack::Default() status_t NetStack::InitCheck() { - return created == true ? B_OK : B_NO_INIT; + bool ready = Default() != NULL; + bool ready3 = ready && (Default()->fEthernetInterface != NULL) && (created == true); + return ready3 ? B_OK : B_NO_INIT; } @@ -162,13 +164,9 @@ NetStack::AddEthernetInterface(EthernetInterface *interface) status_t net_stack_init() { - MSG("enter"); status_t error = NetStack::CreateDefault(); - if (error != B_OK) { - MSG("create default: %x", error); + if (error != B_OK) return error; - } - MSG("created"); //return platform_net_stack_init(); // don't do this here for now diff --git a/src/system/boot/platform/efi/debug.cpp b/src/system/boot/platform/efi/debug.cpp index e64bd1f..dbe8efd 100644 --- a/src/system/boot/platform/efi/debug.cpp +++ b/src/system/boot/platform/efi/debug.cpp @@ -45,22 +45,40 @@ extern "C" uint64 rdtsc(); #ifdef ENABLE_SYSLOG_NG static UDPSocket *sSyslogSocket = NULL; +static bool in_write = false; + +void syslog_write(const char *, size_t); + static void syslog_ng_write(const char *message, size_t length) { - if (NetStack::InitCheck() == B_NO_INIT) + if (in_write == true) return; + in_write = true; + if (NetStack::InitCheck() == B_NO_INIT) { + in_write = false; return; -#if 0 + } + if (sSyslogSocket == NULL) { // Check if the network stack has been initialized yet if (NetStack::Default() != NULL) { sSyslogSocket = new(std::nothrow) UDPSocket; - if (sSyslogSocket == NULL) + if (sSyslogSocket == NULL) { + in_write = false; return; + } sSyslogSocket->Bind(INADDR_ANY, 60514); + } else { + in_write = false; + return; } } + if (sSyslogSocket == NULL) { + in_write = false; + return; + } + // Strip trailing newlines while (length > 0) { if (message[length - 1] != '\n' @@ -69,8 +87,10 @@ syslog_ng_write(const char *message, size_t length) } length--; } - if (length <= 0) + if (length <= 0) { + in_write = false; return; + } char buffer[1500]; const int facility = 0; // kernel @@ -79,13 +99,14 @@ syslog_ng_write(const char *message, size_t length) facility * 8 + severity); length = std::min(length, sizeof(buffer) - offset); memcpy(buffer + offset, message, length); + sSyslogSocket->Send(INADDR_BROADCAST, 514, buffer, offset + length); -#endif + in_write = false; } #endif -static void +void syslog_write(const char* buffer, size_t length) { if (sPostCleanup && sDebugSyslogBuffer != NULL) { diff --git a/src/system/boot/platform/efi/netstack.cpp b/src/system/boot/platform/efi/netstack.cpp index f5dc4db..7c06bf2 100644 --- a/src/system/boot/platform/efi/netstack.cpp +++ b/src/system/boot/platform/efi/netstack.cpp @@ -1,191 +1,178 @@ -/* - * Copyright 2014, Jessica Hamilton, jessica.l.hamilton@xxxxxxxxx. - * Distributed under the terms of the MIT License. - */ - - -#include "efi_platform.h" -#include "efinet.h" - -#include <boot/net/NetStack.h> -#include <boot/net/Ethernet.h> - -#include <KernelExport.h> - -#include <time.h> - - -#define MSG(format, args...) \ - dprintf("%s:%d: " format "\n", __FILE__, __LINE__ , ## args) - - -static EFI_GUID sSimpleNetworkGuid = EFI_SIMPLE_NETWORK_PROTOCOL; - - -class EFIEthernetInterface : public EthernetInterface { -public: - EFIEthernetInterface(); - virtual ~EFIEthernetInterface(); - - status_t Init(); - - virtual mac_addr_t MACAddress() const; - - virtual void *AllocateSendReceiveBuffer(size_t size); - virtual void FreeSendReceiveBuffer(void *buffer); - - virtual ssize_t Send(const void *buffer, size_t size); - virtual ssize_t Receive(void *buffer, size_t size); - -private: - EFI_SIMPLE_NETWORK *fNetwork; - mac_addr_t fMACAddress; -}; - - -EFIEthernetInterface::EFIEthernetInterface() - : - EthernetInterface(), - fNetwork(NULL), - fMACAddress(kNoMACAddress) -{ -} - - -EFIEthernetInterface::~EFIEthernetInterface() -{ - if (fNetwork != NULL) { - fNetwork->Shutdown(fNetwork); - fNetwork->Stop(fNetwork); - fNetwork = NULL; - } -} - - -status_t -EFIEthernetInterface::Init() -{ - EFI_STATUS status = kBootServices->LocateProtocol(&sSimpleNetworkGuid, - NULL, (void **)&fNetwork); - - if (status != EFI_SUCCESS || fNetwork == NULL) { - MSG("locate protocol failed: %x (%p)", status, fNetwork); - return B_ERROR; - } - - status = fNetwork->Shutdown(fNetwork); - MSG("shutting down first, so can start from scratch... %x", status); - - status = fNetwork->Start(fNetwork); - if (status != EFI_SUCCESS && status != EFI_ALREADY_STARTED) { - MSG("failed to start simple network protocol: %x", status); - return B_ERROR; - } - status = fNetwork->Initialize(fNetwork, 0x1000, 0x1000); - if (status != EFI_SUCCESS) { - MSG("failed to initialize simple network protocol: %x", status); - return B_ERROR; - } - - // get MAC address - EFI_MAC_ADDRESS macAddress = fNetwork->Mode->CurrentAddress; - //ASSERT(fNetwork->Mode->HwAddressSize == ETH_ALEN); - #define AT(i) fMACAddress[i] - fMACAddress = macAddress.Addr; - MSG("mac address: %2x:%2x:%2x:%2x:%2x:%2x", AT(0), AT(1), AT(2), AT(3), AT(4), AT(5)); - #undef AT - return B_OK; -} - - -mac_addr_t -EFIEthernetInterface::MACAddress() const -{ - return fMACAddress; -} - - -void * -EFIEthernetInterface::AllocateSendReceiveBuffer(size_t size) -{ - return malloc(size); -} - - -void -EFIEthernetInterface::FreeSendReceiveBuffer(void *buffer) -{ - if (buffer != NULL) - free(buffer); -} - - -ssize_t -EFIEthernetInterface::Send(const void *buffer, size_t size) -{ - EFI_STATUS status = fNetwork->Transmit(fNetwork, 0, size, (void *)buffer, NULL, NULL, NULL); - - if (status == EFI_SUCCESS) { - // Need to wait for packet to be transmitted so we can recyle the transmit buffer - void *txBuffer; - do { - if (fNetwork->GetStatus(fNetwork, NULL, &txBuffer) != EFI_SUCCESS) - return B_ERROR; - - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = 50 * 1000; - nanosleep(&ts, NULL); - } while (txBuffer != buffer); - } - - return size; -} - - -ssize_t -EFIEthernetInterface::Receive(void *buffer, size_t size) -{ - EFI_STATUS status = fNetwork->Receive(fNetwork, NULL, &size, buffer, NULL, NULL, NULL); - - if (status == EFI_NOT_READY) - return 0; - - if (status != EFI_SUCCESS) - return B_ERROR; - - return size; -} - -status_t -platform_net_stack_init() -{ - MSG("enter"); - if (NetStack::Default() == NULL) { - MSG("no memory for default netstack"); - return B_NO_MEMORY; - } - - EFIEthernetInterface *interface = new(std::nothrow) EFIEthernetInterface; - if (!interface) { - MSG("no memory for efi driver"); - return B_NO_MEMORY; - } - - status_t error = interface->Init(); - if (error != B_OK) { - MSG("init efi driver failed"); - delete interface; - return error; - } - - error = NetStack::Default()->AddEthernetInterface(interface); - if (error != B_OK) { - MSG("add efi driver to netstack failed"); - delete interface; - return error; - } - - MSG("exit"); - return B_OK; -} +/* + * Copyright 2014, Jessica Hamilton, jessica.l.hamilton@xxxxxxxxx. + * Distributed under the terms of the MIT License. + */ + + +#include "efi_platform.h" +#include "efinet.h" + +#include <boot/net/NetStack.h> +#include <boot/net/Ethernet.h> + +#include <KernelExport.h> + +#include <time.h> + + +#define MSG(format, args...) \ + dprintf("%s:%d: " format "\n", __FILE__, __LINE__ , ## args) + + +static EFI_GUID sSimpleNetworkGuid = EFI_SIMPLE_NETWORK_PROTOCOL; + + +class EFIEthernetInterface : public EthernetInterface { +public: + EFIEthernetInterface(); + virtual ~EFIEthernetInterface(); + + status_t Init(); + + virtual mac_addr_t MACAddress() const; + + virtual void *AllocateSendReceiveBuffer(size_t size); + virtual void FreeSendReceiveBuffer(void *buffer); + + virtual ssize_t Send(const void *buffer, size_t size); + virtual ssize_t Receive(void *buffer, size_t size); + +private: + EFI_SIMPLE_NETWORK *fNetwork; + mac_addr_t fMACAddress; +}; + + +EFIEthernetInterface::EFIEthernetInterface() + : + EthernetInterface(), + fNetwork(NULL), + fMACAddress(kNoMACAddress) +{ +} + + +EFIEthernetInterface::~EFIEthernetInterface() +{ + if (fNetwork != NULL) { + fNetwork->Shutdown(fNetwork); + fNetwork->Stop(fNetwork); + fNetwork = NULL; + } +} + + +status_t +EFIEthernetInterface::Init() +{ + EFI_STATUS status = kBootServices->LocateProtocol(&sSimpleNetworkGuid, + NULL, (void **)&fNetwork); + + if (status != EFI_SUCCESS || fNetwork == NULL) + return B_ERROR; + + status = fNetwork->Shutdown(fNetwork); + + status = fNetwork->Start(fNetwork); + if (status != EFI_SUCCESS && status != EFI_ALREADY_STARTED) + return B_ERROR; + + status = fNetwork->Initialize(fNetwork, 0, 0); + if (status != EFI_SUCCESS) + return B_ERROR; + + // get MAC address + EFI_MAC_ADDRESS macAddress = fNetwork->Mode->CurrentAddress; + //ASSERT(fNetwork->Mode->HwAddressSize == ETH_ALEN); + #define AT(i) fMACAddress[i] + fMACAddress = macAddress.Addr; + MSG("mac address: %2x:%2x:%2x:%2x:%2x:%2x", AT(0), AT(1), AT(2), AT(3), AT(4), AT(5)); + #undef AT + return B_OK; +} + + +mac_addr_t +EFIEthernetInterface::MACAddress() const +{ + return fMACAddress; +} + + +void * +EFIEthernetInterface::AllocateSendReceiveBuffer(size_t size) +{ + return malloc(size); +} + + +void +EFIEthernetInterface::FreeSendReceiveBuffer(void *buffer) +{ + if (buffer != NULL) + free(buffer); +} + + +ssize_t +EFIEthernetInterface::Send(const void *buffer, size_t size) +{ + EFI_STATUS status = fNetwork->Transmit(fNetwork, 0, size, (void *)buffer, NULL, NULL, NULL); + + if (status == EFI_SUCCESS) { + // Need to wait for packet to be transmitted so we can recyle the transmit buffer + void *txBuffer; + int limit = 10; + do { + if (fNetwork->GetStatus(fNetwork, NULL, &txBuffer) != EFI_SUCCESS) + return B_ERROR; + + struct timespec ts; + ts.tv_sec = 0; + ts.tv_nsec = 50 * 1000; + //nanosleep(&ts, NULL); + } while (txBuffer != buffer && --limit > 0); + + if (limit == 0) + return -1; + } + + return size; +} + + +ssize_t +EFIEthernetInterface::Receive(void *buffer, size_t size) +{ + EFI_STATUS status = fNetwork->Receive(fNetwork, NULL, &size, buffer, NULL, NULL, NULL); + + if (status == EFI_NOT_READY || status != EFI_SUCCESS) + return B_ERROR; + + return size; +} + +status_t +platform_net_stack_init() +{ + if (NetStack::Default() == NULL) + return B_NO_MEMORY; + + EFIEthernetInterface *interface = new(std::nothrow) EFIEthernetInterface; + if (!interface) + return B_NO_MEMORY; + + status_t error = interface->Init(); + if (error != B_OK) { + delete interface; + return error; + } + + error = NetStack::Default()->AddEthernetInterface(interface); + if (error != B_OK) { + delete interface; + return error; + } + + return B_OK; +} ############################################################################ Commit: e5d922335ee69b525d9f8356e674fb9cc49ff83c Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Fri May 2 23:55:08 2014 UTC Replace arch-dependent integer byteswap routines with gcc builtins ---------------------------------------------------------------------------- diff --git a/headers/os/support/ByteOrder.h b/headers/os/support/ByteOrder.h index 96e9961..a0cde4a 100644 --- a/headers/os/support/ByteOrder.h +++ b/headers/os/support/ByteOrder.h @@ -34,9 +34,9 @@ typedef enum { /* always swap macros */ #define B_SWAP_DOUBLE(arg) __swap_double(arg) #define B_SWAP_FLOAT(arg) __swap_float(arg) -#define B_SWAP_INT64(arg) __swap_int64(arg) -#define B_SWAP_INT32(arg) __swap_int32(arg) -#define B_SWAP_INT16(arg) __swap_int16(arg) +#define B_SWAP_INT64(arg) __builtin_bswap64(arg) +#define B_SWAP_INT32(arg) __builtin_bswap32(arg) +#define B_SWAP_INT16(arg) __builtin_bswap16(arg) #if BYTE_ORDER == __LITTLE_ENDIAN /* Host is little endian */ @@ -61,16 +61,16 @@ typedef enum { /* Host native to big endian */ #define B_HOST_TO_BENDIAN_DOUBLE(arg) __swap_double(arg) #define B_HOST_TO_BENDIAN_FLOAT(arg) __swap_float(arg) -#define B_HOST_TO_BENDIAN_INT64(arg) __swap_int64(arg) -#define B_HOST_TO_BENDIAN_INT32(arg) __swap_int32(arg) -#define B_HOST_TO_BENDIAN_INT16(arg) __swap_int16(arg) +#define B_HOST_TO_BENDIAN_INT64(arg) __builtin_bswap64(arg) +#define B_HOST_TO_BENDIAN_INT32(arg) __builtin_bswap32(arg) +#define B_HOST_TO_BENDIAN_INT16(arg) __builtin_bswap16(arg) /* Big endian to host native */ #define B_BENDIAN_TO_HOST_DOUBLE(arg) __swap_double(arg) #define B_BENDIAN_TO_HOST_FLOAT(arg) __swap_float(arg) -#define B_BENDIAN_TO_HOST_INT64(arg) __swap_int64(arg) -#define B_BENDIAN_TO_HOST_INT32(arg) __swap_int32(arg) -#define B_BENDIAN_TO_HOST_INT16(arg) __swap_int16(arg) +#define B_BENDIAN_TO_HOST_INT64(arg) __builtin_bswap64(arg) +#define B_BENDIAN_TO_HOST_INT32(arg) __builtin_bswap32(arg) +#define B_BENDIAN_TO_HOST_INT16(arg) __builtin_bswap16(arg) #else /* BYTE_ORDER */ /* Host is big endian */ @@ -81,16 +81,16 @@ typedef enum { /* Host native to little endian */ #define B_HOST_TO_LENDIAN_DOUBLE(arg) __swap_double(arg) #define B_HOST_TO_LENDIAN_FLOAT(arg) __swap_float(arg) -#define B_HOST_TO_LENDIAN_INT64(arg) __swap_int64(arg) -#define B_HOST_TO_LENDIAN_INT32(arg) __swap_int32(arg) -#define B_HOST_TO_LENDIAN_INT16(arg) __swap_int16(arg) +#define B_HOST_TO_LENDIAN_INT64(arg) __builtin_bswap64(arg) +#define B_HOST_TO_LENDIAN_INT32(arg) __builtin_bswap32(arg) +#define B_HOST_TO_LENDIAN_INT16(arg) __builtin_bswap16(arg) /* Little endian to host native */ #define B_LENDIAN_TO_HOST_DOUBLE(arg) __swap_double(arg) #define B_LENDIAN_TO_HOST_FLOAT(arg) __swap_float(arg) -#define B_LENDIAN_TO_HOST_INT64(arg) __swap_int64(arg) -#define B_LENDIAN_TO_HOST_INT32(arg) __swap_int32(arg) -#define B_LENDIAN_TO_HOST_INT16(arg) __swap_int16(arg) +#define B_LENDIAN_TO_HOST_INT64(arg) __builtin_bswap64(arg) +#define B_LENDIAN_TO_HOST_INT32(arg) __builtin_bswap32(arg) +#define B_LENDIAN_TO_HOST_INT16(arg) __builtin_bswap16(arg) /* Host native to big endian */ #define B_HOST_TO_BENDIAN_DOUBLE(arg) (double)(arg) @@ -111,7 +111,7 @@ typedef enum { #ifdef __cplusplus extern "C" { -#endif +#endif extern status_t swap_data(type_code type, void *data, size_t length, swap_action action); @@ -121,9 +121,6 @@ extern bool is_type_swapped(type_code type); /* Private implementations */ extern double __swap_double(double arg); extern float __swap_float(float arg); -extern uint64 __swap_int64(uint64 arg); -extern uint32 __swap_int32(uint32 arg); -extern uint16 __swap_int16(uint16 arg); #ifdef __cplusplus } ############################################################################ Commit: a9b6d1b5fd385686ca96b24fd86f9e234bf720fb Author: Jessica Hamilton <jessica.l.hamilton@xxxxxxxxx> Date: Sun May 18 08:33:02 2014 UTC Dirty commit of stuff before destroying my VM :p ---------------------------------------------------------------------------- diff --git a/headers/private/app/MessageUtils.h b/headers/private/app/MessageUtils.h index cdd8d36..bf916d3 100644 --- a/headers/private/app/MessageUtils.h +++ b/headers/private/app/MessageUtils.h @@ -132,7 +132,7 @@ template<> inline void byte_swap(int64 &data) { - data = __swap_int64(data); + data = __builtin_bswap64(data); } @@ -140,7 +140,7 @@ template<> inline void byte_swap(uint64 &data) { - data = __swap_int64(data); + data = __builtin_bswap64(data); } @@ -148,7 +148,7 @@ template<> inline void byte_swap(int32 &data) { - data = __swap_int32(data); + data = __builtin_bswap32(data); } @@ -156,7 +156,7 @@ template<> inline void byte_swap(uint32 &data) { - data = __swap_int32(data); + data = __builtin_bswap32(data); } @@ -164,7 +164,7 @@ template<> inline void byte_swap(int16 &data) { - data = __swap_int16(data); + data = __builtin_bswap16(data); } @@ -172,7 +172,7 @@ template<> inline void byte_swap(uint16 &data) { - data = __swap_int16(data); + data = __builtin_bswap16(data); } diff --git a/headers/private/kernel/boot/net/NetStack.h b/headers/private/kernel/boot/net/NetStack.h index cc0ae4f..f2412e7 100644 --- a/headers/private/kernel/boot/net/NetStack.h +++ b/headers/private/kernel/boot/net/NetStack.h @@ -22,6 +22,7 @@ public: ~NetStack(); status_t Init(); + void Destroy(); public: static status_t CreateDefault(); diff --git a/headers/private/kernel/boot/platform.h b/headers/private/kernel/boot/platform.h index 9f3c8eb..ae9ab5e 100644 --- a/headers/private/kernel/boot/platform.h +++ b/headers/private/kernel/boot/platform.h @@ -19,6 +19,7 @@ extern "C" { /* debug functions */ extern void panic(const char *format, ...); extern void dprintf(const char *format, ...); +extern void dprintf_args(const char *format, va_list args); /* heap functions */ extern void platform_release_heap(struct stage2_args *args, void *base); diff --git a/src/kits/app/MessageAdapter.cpp b/src/kits/app/MessageAdapter.cpp index 7e2c5e4..3dfb8d6 100644 --- a/src/kits/app/MessageAdapter.cpp +++ b/src/kits/app/MessageAdapter.cpp @@ -190,7 +190,7 @@ MessageAdapter::Unflatten(uint32 format, BMessage *into, const char *buffer) { r5_message_header *header = (r5_message_header *)buffer; BMemoryIO stream(buffer + sizeof(uint32), - __swap_int32(header->flattened_size) - sizeof(uint32)); + __builtin_bswap32(header->flattened_size) - sizeof(uint32)); return _UnflattenR5Message(format, into, &stream); } @@ -200,7 +200,7 @@ MessageAdapter::Unflatten(uint32 format, BMessage *into, const char *buffer) dano_section_header *header = (dano_section_header *)buffer; ssize_t size = header->size; if (header->code == MESSAGE_FORMAT_DANO_SWAPPED) - size = __swap_int32(size); + size = __builtin_bswap32(size); BMemoryIO stream(buffer + sizeof(uint32), size - sizeof(uint32)); return _UnflattenDanoMessage(format, into, &stream); @@ -622,7 +622,7 @@ MessageAdapter::_UnflattenR5Message(uint32 format, BMessage *into, } else { for (int32 i = 0; i < itemCount; i++) { if (!fixedSize) { - itemSize = __swap_int32(*(int32 *)pointer); + itemSize = __builtin_bswap32(*(int32 *)pointer); pointer += sizeof(int32); } diff --git a/src/kits/support/ByteOrder.cpp b/src/kits/support/ByteOrder.cpp index c009a5f..48da7fb 100644 --- a/src/kits/support/ByteOrder.cpp +++ b/src/kits/support/ByteOrder.cpp @@ -39,7 +39,7 @@ swap_data(type_code type, void *_data, size_t length, swap_action action) uint16 *end = (uint16 *)((addr_t)_data + length); while (data < end) { - *data = __swap_int16(*data); + *data = __builtin_bswap16(*data); data++; } break; @@ -62,7 +62,7 @@ swap_data(type_code type, void *_data, size_t length, swap_action action) uint32 *end = (uint32 *)((addr_t)_data + length); while (data < end) { - *data = __swap_int32(*data); + *data = __builtin_bswap32(*data); data++; } break; @@ -83,7 +83,7 @@ swap_data(type_code type, void *_data, size_t length, swap_action action) uint64 *end = (uint64 *)((addr_t)_data + length); while (data < end) { - *data = __swap_int64(*data); + *data = __builtin_bswap64(*data); data++; } break; @@ -99,9 +99,9 @@ swap_data(type_code type, void *_data, size_t length, swap_action action) BMessenger::Private messengerPrivate(messenger); // ToDo: if the additional fields change, this function has to be updated! messengerPrivate.SetTo( - __swap_int32(messengerPrivate.Team()), - __swap_int32(messengerPrivate.Port()), - __swap_int32(messengerPrivate.Token())); + __builtin_bswap32(messengerPrivate.Team()), + __builtin_bswap32(messengerPrivate.Port()), + __builtin_bswap32(messengerPrivate.Token())); messenger++; } break; diff --git a/src/system/boot/arch/x86/Jamfile b/src/system/boot/arch/x86/Jamfile index fbb177c..0f15ac3 100644 --- a/src/system/boot/arch/x86/Jamfile +++ b/src/system/boot/arch/x86/Jamfile @@ -42,4 +42,4 @@ SEARCH on [ FGristFiles $(kernelLibArchSpecificSources) ] } SEARCH on [ FGristFiles $(librootOsArchSources) ] - = [ FDirName $(HAIKU_TOP) src system libroot os arch x86 ] ; + = [ FDirName $(HAIKU_TOP) src system libroot os arch $(TARGET_ARCH) ] ; diff --git a/src/system/boot/loader/file_systems/packagefs/packagefs.cpp b/src/system/boot/loader/file_systems/packagefs/packagefs.cpp index 5223662..0e0ece8 100644 --- a/src/system/boot/loader/file_systems/packagefs/packagefs.cpp +++ b/src/system/boot/loader/file_systems/packagefs/packagefs.cpp @@ -286,6 +286,7 @@ struct PackageLoaderErrorOutput : BErrorOutput { virtual void PrintErrorVarArgs(const char* format, va_list args) { + dprintf_args(format, args); } }; diff --git a/src/system/boot/loader/net/NetStack.cpp b/src/system/boot/loader/net/NetStack.cpp index 03bc995..72fe7ae 100644 --- a/src/system/boot/loader/net/NetStack.cpp +++ b/src/system/boot/loader/net/NetStack.cpp @@ -36,6 +36,11 @@ NetStack::NetStack() // destructor NetStack::~NetStack() { +} + +void +NetStack::Destroy() +{ delete fTCPService; delete fUDPService; delete fIPService; @@ -128,7 +133,8 @@ status_t NetStack::ShutDown() { if (sNetStack != NULL) { - delete sNetStack; + created = false; + sNetStack->Destroy(); sNetStack = NULL; } diff --git a/src/system/boot/platform/efi/debug.cpp b/src/system/boot/platform/efi/debug.cpp index dbe8efd..7cd8ac5 100644 --- a/src/system/boot/platform/efi/debug.cpp +++ b/src/system/boot/platform/efi/debug.cpp @@ -118,7 +118,7 @@ syslog_write(const char* buffer, size_t length) } -static void +void dprintf_args(const char *format, va_list args) { char buffer[512];