Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libxenon.dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM free60/toolchain:latest

RUN apt update && apt install nano && \
RUN apt update && apt install nano bc && \
apt -y clean autoclean autoremove && \
rm -rf /var/lib/{apt,dpkg,cache,log}/

Expand Down
7 changes: 6 additions & 1 deletion libxenon/drivers/lwip/xenon/netif/enet.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//#include "lwipopts.h"
#include <stdlib.h>
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
Expand Down Expand Up @@ -182,7 +183,11 @@ err_t enet_init(struct netif *netif)
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;

#if LWIP_NETIF_HOSTNAME
netif->hostname = "XeLL";
// Make this a unique identifier using the MAC address as a base.
// It should help with DHCP assignment or rebinding issues.
char *gen_hostname;
asprintf(&gen_hostname, "%02X%02X%02X%02X%02X%02X-xenon", netif->hwaddr[0], netif->hwaddr[1], netif->hwaddr[2], netif->hwaddr[3], netif->hwaddr[4], netif->hwaddr[5]);
netif->hostname = gen_hostname;
#endif

//printf("NETIF at %p\n", netif);
Expand Down
8 changes: 5 additions & 3 deletions libxenon/drivers/network/network.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,11 @@ void network_init()

dhcp_wait=mftb();
int i = 0;
while (netif.ip_addr.addr==0 && i < 60) {
// Extend timeouts to accomodate slower network links such as wireless<->ethernet bridges
while (netif.ip_addr.addr==0 && i < 90) {
network_poll();
now2=mftb();
if (tb_diff_msec(now2, dhcp_wait) >= 250){
if (tb_diff_msec(now2, dhcp_wait) >= 300){
dhcp_wait=mftb();
i++;
if (i % 2)
Expand Down Expand Up @@ -120,7 +121,8 @@ void network_print_config()
{
printf(" * network config: %d.%d.%d.%d / %d.%d.%d.%d\n",
NTOA(netif.ip_addr), NTOA(netif.netmask));
printf(" MAC: %02X%02X%02X%02X%02X%02X\n\n",
// Add colon separators for the PHY MAC address.
printf(" MAC: %02X:%02X:%02X:%02X:%02X:%02X\n\n",
netif.hwaddr[0], netif.hwaddr[1], netif.hwaddr[2],
netif.hwaddr[3], netif.hwaddr[4], netif.hwaddr[5]);
}
Expand Down
67 changes: 52 additions & 15 deletions libxenon/drivers/ppc/c_except.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
#include <console/console.h>
#include <console/telnet_console.h>
#include <input/input.h>
#include <usb/usbmain.h>
#include <ppc/cache.h>
#include <ppc/register.h>
#include <stdio.h>
Expand Down Expand Up @@ -73,6 +76,9 @@ void crashdump(u32 exception,u64 * context)
if(!xenos_is_initialized())
xenos_init(VIDEO_MODE_AUTO);

// Enable stack dump capture over telnet
telnet_console_init();

console_set_colors(0x000080ff, 0xffffffff);
console_init();
console_clrscr();
Expand All @@ -94,28 +100,59 @@ void crashdump(u32 exception,u64 * context)
for(i=0;i<8;++i)
sprintf(text,"%s%02d=%016llx %02d=%016llx %02d=%016llx %02d=%016llx\n",
text,i,context[i],i+8,context[i+8],i+16,context[i+16],i+24,context[i+24]);

flush_console();

_cpu_print_stack((void*)(u32)context[36],(void*)(u32)context[32],(void*)(u32)context[1]);
strcat(text,"\n\nOn uart: 'x'=Xell, 'h'=Halt, 'r'=Reboot\n\n");

strcat(text,"\n\nOn telnet or uart: 'x'=Soft reboot to XeLL, 'h'=Shutdown, 'r'=Hard reboot\n\nOn controller: 'x'=Soft reboot to XeLL, 'y'=Shutdown, 'b'=Hard Reboot\n\n\n");

flush_console();

// September 26 2025 - add more crash handling options.
// If using telnet you can capture the stack trace over the network instead of needing UART cabling.
// Caveat: if networking crashed in the program beforehand, YMMV :)

// Add also controller support to take an action in case of stack dump.
struct controller_data_s controller;
struct controller_data_s button;

for(;;){
switch(getch()){
case 'x':
// Read controller input
if (get_controller_data(&button, 0)){
if((button.x)&&(!controller.x)){
exit(0);
break;
case 'h':
xenon_smc_power_shutdown();
for(;;);
break;
case 'r':
xenon_smc_power_reboot();
for(;;);
break;
}
if((button.y)&&(!controller.y)){
xenon_smc_power_shutdown();
for(;;);
break;
}
if((button.b)&&(!controller.b)){
xenon_smc_power_reboot();
for(;;);
break;
}
controller=button;
}
usb_do_poll();

// Read UART char or telnet
if(kbhit()){
switch(getch()){
case 'x':
exit(0);
break;
case 'h':
xenon_smc_power_shutdown();
for(;;);
break;
case 'r':
xenon_smc_power_reboot();
for(;;);
break;
}
}
}
}
}