diff --git a/.gitignore b/.gitignore index 2661f93775..239d3823de 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ size.report .obj *.elf bin +*.debug \ No newline at end of file diff --git a/Kernel/platform/platform-rpipico/.gitignore b/Kernel/platform/platform-rpipico/.gitignore new file mode 100644 index 0000000000..41ac95dc75 --- /dev/null +++ b/Kernel/platform/platform-rpipico/.gitignore @@ -0,0 +1,7 @@ +utils/progbase.h +utils/ps +utils/ps.c +utils/*.o +filesystem.* +uf2conv + diff --git a/Kernel/platform/platform-rpipico/CMakeLists.txt b/Kernel/platform/platform-rpipico/CMakeLists.txt index 8dcb7aa290..5838a56f1a 100644 --- a/Kernel/platform/platform-rpipico/CMakeLists.txt +++ b/Kernel/platform/platform-rpipico/CMakeLists.txt @@ -8,6 +8,20 @@ set(CMAKE_C_STANDARD 11) set(CMAKE_BUILD_TYPE Debug) set(PICO_COPY_TO_RAM 1) +add_compile_definitions( + PICO_HEAP_SIZE=0x0 + PICO_NO_BINARY_INFO=1 + PICO_TIME_DEFAULT_ALARM_POOL_DISABLED + PICO_NO_GC_SECTIONS + ) + +remove_definitions( + LIB_PICO_STDIO_UART + LIB_PICO_STDIO_USB + LIB_PICO_STDIO_SEMIHOSTING + PICO_NO_GC_SECTIONS +) + pico_sdk_init() include_directories( @@ -20,13 +34,16 @@ include_directories( add_executable(fuzix devices.c + devrpi.c devflash.c devsdspi.c + #/*devsdspidma.c*/ devtty.c elf.c main.c misc.c rawflash.c + rawuart.c swapper.c tricks.S core1.c @@ -70,9 +87,7 @@ target_link_libraries(fuzix pico_multicore hardware_flash hardware_spi - hardware_uart - tinyusb_device_unmarked - tinyusb_board + tinyusb_device ) pico_set_float_implementation(fuzix none) diff --git a/Kernel/platform/platform-rpipico/Makefile b/Kernel/platform/platform-rpipico/Makefile index 8d79785323..8e9fcf9b0d 100644 --- a/Kernel/platform/platform-rpipico/Makefile +++ b/Kernel/platform/platform-rpipico/Makefile @@ -20,6 +20,9 @@ image:: world uf2conv arm-none-eabi-objcopy -I binary -O elf32-littlearm --change-section-vma .data=0x10018000 filesystem.ftl filesystem.elf ./uf2conv filesystem.ftl filesystem.uf2 0x10018000 +image-sd:: world uf2conv + ./update-flash.sh sd + clean: rm -rf build $(MAKE) -C ../../../Library/libs -f Makefile.armm0 clean @@ -31,6 +34,7 @@ clean: $(MAKE) -C ../../../Applications/cave -f Makefile.armm0 clean $(MAKE) -C ../../../Applications/cursesgames -f Makefile.armm0 clean $(MAKE) -C ../../../Standalone clean + $(MAKE) -C utils clean world: build/fuzix.elf $(MAKE) -C ../../../Library/libs -f Makefile.armm0 @@ -42,6 +46,7 @@ world: build/fuzix.elf $(MAKE) -C ../../../Applications/cave -f Makefile.armm0 $(MAKE) -C ../../../Applications/cursesgames -f Makefile.armm0 $(MAKE) -C ../../../Standalone + $(MAKE) -C utils uf2conv: tools/uf2conv.c cc -O -g -o $@ $< diff --git a/Kernel/platform/platform-rpipico/README.md b/Kernel/platform/platform-rpipico/README.md index 0635dc7216..ac68a1366e 100644 --- a/Kernel/platform/platform-rpipico/README.md +++ b/Kernel/platform/platform-rpipico/README.md @@ -121,6 +121,14 @@ You can't turn swap off again. You probably can swap to the NAND flash, but it's a terrible idea. +## Boot device + +Edit config.h to select appropriate boot device. + +`#define BOOTDEVICE 0x0000` - for NAND flash (hda) + +`#define BOOTDEVICE 0x0011` - for the first partioin on the SD card (hdb1) + ## Using the NAND flash The Pico's built-in NAND flash is supported, appearing as `/dev/hda` insize @@ -131,6 +139,13 @@ gets notified when sectors become free, but if the filesystem gets very full and Dhara runs out it can get extremely slow as it constantly does garbage collection. +## Using SD Card + +1. Create dos partition table + * Partition 1: 32MB partition + * Partition 2: 4MB partition (optional) +2. Run `dd if=filesystem.img bs=512 seek=2048 of=/dev/sdX conv=notrunc status=progress` to copy image onto SD card. (**Be careful to not damage your system drive**) + ## Issues There are many, the biggest of which are: diff --git a/Kernel/platform/platform-rpipico/config.h b/Kernel/platform/platform-rpipico/config.h index f73f63c45e..d04bee32b3 100644 --- a/Kernel/platform/platform-rpipico/config.h +++ b/Kernel/platform/platform-rpipico/config.h @@ -1,3 +1,6 @@ +#ifndef CONFIG_H +#define CONFIG_H +#include "tusb_config.h" /* * Set this according to your SD card pins (default * is the David Given arrangement). @@ -42,13 +45,22 @@ #undef CONFIG_VT #undef CONFIG_FONT8X8 +/* Disable block device in flash. Warning, it's unstable. */ +#define PICO_DISABLE_FLASH + /* Program layout */ +#ifndef PICO_DISABLE_FLASH +#define FLASHCODESIZE 7 +#else +#define FLASHCODESIZE 0 +#endif + +#define USERMEM ((172-FLASHCODESIZE)*1024) #define UDATA_BLKS 3 #define UDATA_SIZE (UDATA_BLKS << BLKSHIFT) -#define USERMEM (160*1024) #define PROGSIZE (65536 - UDATA_SIZE) -extern uint8_t progbase[USERMEM]; +extern char progbase[USERMEM]; #define udata (*(struct u_data*)progbase) #define USERSTACK (4*1024) /* 4kB */ @@ -69,11 +81,16 @@ extern uint8_t progbase[USERMEM]; /* We need a tidier way to do this from the loader */ #define CMDLINE NULL /* Location of root dev name */ -#define BOOTDEVICE 0x0000 /* hda */ +#define BOOTDEVICE 0x0011 /* hda 0x0000 hdb1 0x0011 */ #define SWAPDEV (swap_dev) /* dynamic swap */ /* Device parameters */ -#define NUM_DEV_TTY 1 +#define NUM_DEV_TTY_UART 1 +#define NUM_DEV_TTY_USB (CFG_TUD_CDC) +#define NUM_DEV_TTY (NUM_DEV_TTY_UART + NUM_DEV_TTY_USB) + +#define USB_TO_TTY(x) (x + 1 + NUM_DEV_TTY_UART) +#define TTY_TO_USB(x) (x - 1 - NUM_DEV_TTY_UART) #define TTYDEV BOOT_TTY /* Device used by kernel for messages, panics */ #define NBUFS 20 /* Number of block buffers */ @@ -91,5 +108,5 @@ extern uint8_t progbase[USERMEM]; #define MANGLED 1 #include "mangle.h" +#endif // vim: sw=4 ts=4 et - diff --git a/Kernel/platform/platform-rpipico/core1.c b/Kernel/platform/platform-rpipico/core1.c index d000388421..0ab7a110d4 100644 --- a/Kernel/platform/platform-rpipico/core1.c +++ b/Kernel/platform/platform-rpipico/core1.c @@ -4,83 +4,173 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include +#include "picosdk.h" +#include "config.h" +#include "core1.h" + #include -#include -#include -#include +#include #include #include #include -#include "core1.h" -bool usbconsole_is_readable(void) +#define CONFIG_CONSOLE_BUF_LEN 16 + +#if CONFIG_CONSOLE_BUF_LEN > 255 +#error "Invalid console buffer length" +#endif + +struct console_buf_t { - return multicore_fifo_rvalid(); + uint8_t buffer[CONFIG_CONSOLE_BUF_LEN]; + uint8_t rindex; + uint8_t windex; + uint8_t len; +}; + +struct console_t +{ + struct console_buf_t rbuf; + struct console_buf_t wbuf; + bool sleeping; +}; + +static struct console_t console_table[NUM_DEV_TTY_USB]; +critical_section_t critical_section; + +static void console_buf_write(struct console_buf_t *buf, uint8_t b) +{ + /* + can deadlock core1 thread + while(buf->len >= CONFIG_CONSOLE_BUF_LEN) + tight_loop_contents(); + */ + critical_section_enter_blocking(&critical_section); + if(buf->len < CONFIG_CONSOLE_BUF_LEN) + { + buf->buffer[buf->windex] = b; + buf->windex = (buf->windex + 1) % CONFIG_CONSOLE_BUF_LEN; + buf->len++; + } + critical_section_exit(&critical_section); } -bool usbconsole_is_writable(void) +static uint8_t console_buf_read(struct console_buf_t *buf) { - return multicore_fifo_wready(); + critical_section_enter_blocking(&critical_section); + if(buf->len == 0) + { + panic("rd undrf"); + } + uint8_t b = buf->buffer[buf->rindex]; + buf->rindex = (buf->rindex + 1) % CONFIG_CONSOLE_BUF_LEN; + buf->len--; + critical_section_exit(&critical_section); + return b; } -uint8_t usbconsole_getc_blocking(void) +int usbconsole_read(uint8_t *buffer, int size) { - return multicore_fifo_pop_blocking(); + if(size & 0x01) + { + panic("buf size"); + } + int written = 0; + for(int i = 0; i < NUM_DEV_TTY && written < size; i++) + { + struct console_buf_t *buf = &console_table[i].rbuf; + if (buf->len > 0) + { + buffer[0] = USB_TO_TTY(i); + buffer[1] = console_buf_read(buf); + buffer += 2; + written += 2; + } + } + return written; } -void usbconsole_putc_blocking(uint8_t b) +extern bool usbconsole_is_writable(uint8_t minor) { - multicore_fifo_push_blocking(b); + minor = TTY_TO_USB(minor); + return console_table[minor].wbuf.len < CONFIG_CONSOLE_BUF_LEN; } -static void core1_main(void) +extern bool usbconsole_is_available(uint8_t minor) +{ + minor = TTY_TO_USB(minor); + return minor <= NUM_DEV_TTY_USB; +} + +extern void usbconsole_putc(uint8_t minor, uint8_t b) +{ + minor = TTY_TO_USB(minor); + if (minor >= NUM_DEV_TTY_USB) + { + panic("ttydev"); + } + struct console_buf_t *buf = &console_table[minor].wbuf; + if (buf->len >= CONFIG_CONSOLE_BUF_LEN) + { + panic("ovf"); + } + + if (!console_table[minor].wbusy) + { + console_buf_write(buf, b); + } +} + +extern void usbconsole_setsleep(uint8_t minor, bool sleeping) { - uart_init(uart_default, PICO_DEFAULT_UART_BAUD_RATE); - gpio_set_function(PICO_DEFAULT_UART_TX_PIN, GPIO_FUNC_UART); - gpio_set_function(PICO_DEFAULT_UART_RX_PIN, GPIO_FUNC_UART); - uart_set_translate_crlf(uart_default, false); - uart_set_fifo_enabled(uart_default, true); + console_table[TTY_TO_USB(minor)].sleeping = sleeping; +} - tusb_init(); +extern bool usbconsole_is_sleeping(uint8_t minor) +{ + return console_table[TTY_TO_USB(minor)].sleeping; +} + +static void core1_main(void) +{ + tusb_init(); for (;;) { tud_task(); - if (multicore_fifo_rvalid() - && (!tud_cdc_connected() || tud_cdc_write_available()) - && uart_is_writable(uart_default)) + /* + We ignore tud_cdc_n_connected because if DTR is not set by the host + all tty's will appear disconnected, which seems to be the case for pi pico + */ + for (int i = 0; i < CFG_TUD_CDC; i++) { - int b = multicore_fifo_pop_blocking(); + console_table[i].wbusy = 0; + } - if (tud_cdc_connected()) + for(int i = 0; i < CFG_TUD_CDC; i++) + { + if (tud_cdc_n_write_available(i) + && console_table[i].wbuf.len) { - tud_cdc_write(&b, 1); - tud_cdc_write_flush(); + uint8_t b = console_buf_read(&console_table[i].wbuf); + tud_cdc_n_write_char(i, b); + tud_cdc_n_write_flush(i); } - - uart_putc(uart_default, b); } - if (multicore_fifo_wready() - && ((tud_cdc_connected() && tud_cdc_available()) - || uart_is_readable(uart_default))) + for (int i = 0; i < CFG_TUD_CDC; i++) { - /* Only service a byte from CDC *or* the UART, in case two show - * up at the same time and we end up blocking. No big loss, the - * next one will be read the next time around the loop. */ - - if (tud_cdc_available()) + if (!tud_cdc_n_available(i)) { - uint8_t b; - int count = tud_cdc_read(&b, 1); - if (count) - multicore_fifo_push_blocking(b); + continue; } - else if (uart_is_readable(uart_default)) + struct console_buf_t *buf = &console_table[i].rbuf; + if (buf->len < CONFIG_CONSOLE_BUF_LEN) { - uint8_t b = uart_get_hw(uart_default)->dr; - multicore_fifo_push_blocking(b); + uint8_t b = tud_cdc_n_read_char(i); + console_buf_write(buf, b); } } } @@ -88,6 +178,7 @@ static void core1_main(void) void core1_init(void) { + multicore_reset_core1(); + critical_section_init(&critical_section); multicore_launch_core1(core1_main); } - diff --git a/Kernel/platform/platform-rpipico/core1.h b/Kernel/platform/platform-rpipico/core1.h index 917991a0bf..26f737480c 100644 --- a/Kernel/platform/platform-rpipico/core1.h +++ b/Kernel/platform/platform-rpipico/core1.h @@ -3,10 +3,13 @@ extern void core1_init(void); -extern bool usbconsole_is_readable(void); -extern bool usbconsole_is_writable(void); -extern uint8_t usbconsole_getc_blocking(void); -extern void usbconsole_putc_blocking(uint8_t b); +extern int usbconsole_read(uint8_t *buffer, int size); +extern bool usbconsole_is_writable(uint8_t minor); +extern bool usbconsole_is_available(uint8_t minor); +extern void usbconsole_putc(uint8_t minor, uint8_t b); +extern void usbconsole_setsleep(uint8_t minor, bool sleeping); +extern bool usbconsole_is_sleeping(uint8_t minor); + #endif diff --git a/Kernel/platform/platform-rpipico/devflash.c b/Kernel/platform/platform-rpipico/devflash.c index caf4f0e9ac..6126e17b5a 100644 --- a/Kernel/platform/platform-rpipico/devflash.c +++ b/Kernel/platform/platform-rpipico/devflash.c @@ -1,10 +1,12 @@ #include -#include +#include + +#ifndef PICO_DISABLE_FLASH #include #include #include +#include #include -#include #include "lib/dhara/map.h" #include "lib/dhara/nand.h" #include "globals.h" @@ -53,7 +55,7 @@ int dhara_nand_copy(const struct dhara_nand *n, return dhara_nand_prog(&nand, dst, tmp_buf, err); } -static uint_fast8_t transfer_cb(void) +static uint_fast8_t devflash_transfer(void) { dhara_error_t err = DHARA_E_NONE; if (blk_op.is_read) @@ -64,7 +66,7 @@ static uint_fast8_t transfer_cb(void) return (err == DHARA_E_NONE); } -static int trim_cb(void) +static int devflash_trim(void) { dhara_sector_t sector = blk_op.lba; if (sector < (nand.num_blocks << nand.log2_ppb)) @@ -72,12 +74,41 @@ static int trim_cb(void) return 0; } +static int devflash_flush(void) +{ + dhara_error_t err; + int res = dhara_map_sync(&dhara, &err); + if(res < 0) + { + udata.u_error = EIO; + return -1; + } + return 0; +} +#else +static uint_fast8_t devflash_transfer() +{ + udata.u_error = EIO; + return -1; +} +static int devflash_flush() +{ + udata.u_error = EIO; + return -1; +} +static int devflash_trim() +{ + udata.u_error = EIO; + return -1; +} +#endif + void flash_dev_init(void) { blkdev_t* blk = blkdev_alloc(); if (!blk) return; - +#ifndef PICO_DISABLE_FLASH kprintf("NAND flash, "); dhara_map_init(&dhara, &nand, journal_buf, 10); dhara_error_t err = DHARA_E_NONE; @@ -85,14 +116,14 @@ void flash_dev_init(void) uint32_t lba = dhara_map_capacity(&dhara); kprintf("%dkB physical %dkB logical at 0x%p: ", nand.num_blocks * 4, lba / 2, XIP_NOCACHE_NOALLOC_BASE + FLASH_OFFSET); - - blk->transfer = transfer_cb; + blk->drive_lba_count = lba; +#endif + blk->transfer = devflash_transfer; + blk->flush = devflash_flush; #ifdef CONFIG_TRIM - blk->trim = trim_cb; + blk->trim = devflash_trim; #endif - blk->drive_lba_count = lba; blkdev_scan(blk, 0); } -/* vim: sw=4 ts=4 et: */ - +/* vim: sw=4 ts=4 et: */ \ No newline at end of file diff --git a/Kernel/platform/platform-rpipico/devices.c b/Kernel/platform/platform-rpipico/devices.c index 07841d35ff..b876812105 100644 --- a/Kernel/platform/platform-rpipico/devices.c +++ b/Kernel/platform/platform-rpipico/devices.c @@ -10,9 +10,15 @@ #include "globals.h" #include "picosdk.h" #include -#include #include #include "core1.h" +#include "devrpi.h" +#include "rawuart.h" + +extern char __StackLimit; /* Set by linker. */ +extern char __HeapLimit; /* Set by linker. */ + +#define UNUSEDSIZE ((void*)(&__StackLimit) - (void*)(&__HeapLimit)) struct devsw dev_tab[] = /* The device driver switch table */ { @@ -28,6 +34,14 @@ struct devsw dev_tab[] = /* The device driver switch table */ { no_open, no_close, no_rdwr, no_rdwr, no_ioctl }, /* 4: /dev/mem etc System devices (one offs) */ { no_open, no_close, sys_read, sys_write, sys_ioctl }, + /* 5 */ + { nxio_open, no_close, no_rdwr, no_rdwr, no_ioctl }, + /* 6 */ + { nxio_open, no_close, no_rdwr, no_rdwr, no_ioctl }, + /* 7 */ + { nxio_open, no_close, no_rdwr, no_rdwr, no_ioctl }, + /* 8 /dev/pico */ + { no_open, no_close, no_rdwr, rpi_write, no_ioctl } /* Pack to 7 with nxio if adding private devices and start at 8 */ }; @@ -52,21 +66,20 @@ static void timer_tick_cb(unsigned alarm) update_us_since_boot(&next, time_us_64() + (1000000 / TICKSPERSEC)); hardware_alarm_set_target(0, next); } - + irqflags_t irq = di(); + udata.u_ininterrupt = 1; + tty_interrupt(); timer_interrupt(); - - if (usbconsole_is_readable()) - { - uint8_t c = usbconsole_getc_blocking(); - tty_inproc(minor(BOOT_TTY), c); - } + udata.u_ininterrupt = 0; + irqrestore(irq); } void device_init(void) { + kprintf("Unallocated RAM: %dkB\n", UNUSEDSIZE / 1024); + /* The flash device is too small to be useful, and a corrupt flash will * cause a crash on startup... oddly. */ - flash_dev_init(); sd_rawinit(); @@ -75,7 +88,7 @@ void device_init(void) hardware_alarm_claim(0); update_us_since_boot(&now, time_us_64()); hardware_alarm_set_callback(0, timer_tick_cb); - timer_tick_cb(0); + hardware_alarm_force_irq(0); } /* vim: sw=4 ts=4 et: */ diff --git a/Kernel/platform/platform-rpipico/devrpi.c b/Kernel/platform/platform-rpipico/devrpi.c new file mode 100644 index 0000000000..e4b7017f6e --- /dev/null +++ b/Kernel/platform/platform-rpipico/devrpi.c @@ -0,0 +1,15 @@ +#include +#include "picosdk.h" +#include + +int rpi_write(uint_fast8_t minor, uint_fast8_t rawflag, uint_fast8_t flag) +{ + switch(minor) + { + case 0: + reset_usb_boot(0, 0); + return 0; /* Will never execute */ + default: + return -1; + } +} \ No newline at end of file diff --git a/Kernel/platform/platform-rpipico/devrpi.h b/Kernel/platform/platform-rpipico/devrpi.h new file mode 100644 index 0000000000..c1f4b04ffb --- /dev/null +++ b/Kernel/platform/platform-rpipico/devrpi.h @@ -0,0 +1,6 @@ +#ifndef DEVBOOT_H +#define DEVBOOT_H + +int rpi_write(uint_fast8_t minor, uint_fast8_t rawflag, uint_fast8_t flag); + +#endif \ No newline at end of file diff --git a/Kernel/platform/platform-rpipico/devtty.c b/Kernel/platform/platform-rpipico/devtty.c index 3bae76b3f9..ba43f8e51d 100644 --- a/Kernel/platform/platform-rpipico/devtty.c +++ b/Kernel/platform/platform-rpipico/devtty.c @@ -4,35 +4,84 @@ #include #include #include +#include "rawuart.h" #include "picosdk.h" #include #include "core1.h" -static uint8_t ttybuf[TTYSIZ]; +static uint8_t ttybuf[TTYSIZ*NUM_DEV_TTY]; struct s_queue ttyinq[NUM_DEV_TTY+1] = { /* ttyinq[0] is never used */ { 0, 0, 0, 0, 0, 0 }, - { ttybuf, ttybuf, ttybuf, TTYSIZ, 0, TTYSIZ/2 }, + { &ttybuf[0], &ttybuf[0], &ttybuf[0], TTYSIZ, 0, TTYSIZ/2 }, +#if NUM_DEV_TTY_USB >= 1 + { &ttybuf[TTYSIZ*1], &ttybuf[TTYSIZ*1], &ttybuf[TTYSIZ*1], TTYSIZ, 0, TTYSIZ/2 }, +#endif +#if NUM_DEV_TTY_USB >= 2 + { &ttybuf[TTYSIZ*2], &ttybuf[TTYSIZ*2], &ttybuf[TTYSIZ*2], TTYSIZ, 0, TTYSIZ/2 }, +#endif +#if NUM_DEV_TTY_USB >= 3 + { &ttybuf[TTYSIZ*3], &ttybuf[TTYSIZ*3], &ttybuf[TTYSIZ*3], TTYSIZ, 0, TTYSIZ/2 }, +#endif +#if NUM_DEV_TTY_USB >= 4 + { &ttybuf[TTYSIZ*4], &ttybuf[TTYSIZ*4], &ttybuf[TTYSIZ*4], TTYSIZ, 0, TTYSIZ/2 }, +#endif }; -tcflag_t termios_mask[NUM_DEV_TTY+1] = { 0, _CSYS }; +tcflag_t termios_mask[NUM_DEV_TTY+1] = { + 0, + _CSYS, +#if NUM_DEV_TTY_USB >= 1 + _CSYS, +#endif +#if NUM_DEV_TTY_USB >= 2 + _CSYS, +#endif +#if NUM_DEV_TTY_USB >= 3 + _CSYS, +#endif +#if NUM_DEV_TTY_USB >= 4 + _CSYS, +#endif +}; /* Output for the system console (kprintf etc) */ void kputchar(uint_fast8_t c) { if (c == '\n') - usbconsole_putc_blocking('\r'); - usbconsole_putc_blocking(c); + uart1_putc('\r'); + //usbconsole_putc_blocking(minor(TTYDEV), c); + //usbconsole_putc_debug(c); + uart1_putc(c); } void tty_putc(uint_fast8_t minor, uint_fast8_t c) { - kputchar(c); + + if (minor == 1) + { + uart1_putc(c); + } + else + { + usbconsole_putc(minor, c); + } } ttyready_t tty_writeready(uint_fast8_t minor) { - return usbconsole_is_writable() ? TTY_READY_NOW : TTY_READY_SOON; + if (minor == 1) + { + return uart1_ready() ? TTY_READY_NOW : TTY_READY_SOON; + } + else + { + if (usbconsole_is_writable(minor)) + { + return TTY_READY_NOW; + } + return TTY_READY_SOON; + } } /* For the moment */ @@ -41,9 +90,30 @@ int tty_carrier(uint_fast8_t minor) return 1; } -void tty_sleeping(uint_fast8_t minor) {} +void tty_sleeping(uint_fast8_t minor) +{ + if(minor != 1) + { + usbconsole_setsleep(minor, true); + } +} void tty_data_consumed(uint_fast8_t minor) {} void tty_setup(uint_fast8_t minor, uint_fast8_t flags) {} +void tty_interrupt() +{ + int c; + while ((c = uart1_getc()) >= 0) + { + tty_inproc(1, (char)c); + } + + uint8_t cbuf[8]; + int w = usbconsole_read(cbuf, sizeof(cbuf)); + for (int i = 0; i < w; i += 2) + { + tty_inproc(cbuf[i], cbuf[i + 1]); + } +} /* vim: sw=4 ts=4 et: */ diff --git a/Kernel/platform/platform-rpipico/devtty.h b/Kernel/platform/platform-rpipico/devtty.h index c387e9045b..8870fe1c84 100644 --- a/Kernel/platform/platform-rpipico/devtty.h +++ b/Kernel/platform/platform-rpipico/devtty.h @@ -1,4 +1,6 @@ #ifndef __DEVTTY_DOT_H__ #define __DEVTTY_DOT_H__ +extern void tty_interrupt(); + #endif diff --git a/Kernel/platform/platform-rpipico/main.c b/Kernel/platform/platform-rpipico/main.c index 8108496f07..dc4677426f 100644 --- a/Kernel/platform/platform-rpipico/main.c +++ b/Kernel/platform/platform-rpipico/main.c @@ -1,6 +1,9 @@ #include #include +#include "rawuart.h" #include "picosdk.h" +#include +#include #include "kernel-armm0.def" #include "globals.h" #include "printf.h" @@ -47,6 +50,7 @@ void syscall_handler(struct svc_frame* eh) int main(void) { + uart1_init(); core1_init(); if ((U_DATA__U_SP_OFFSET != offsetof(struct u_data, u_sp)) || @@ -64,6 +68,7 @@ int main(void) ramsize = (SRAM_END - SRAM_BASE) / 1024; procmem = USERMEM / 1024; + //turn on power led gpio_init(POWER_LED); gpio_set_dir(POWER_LED, GPIO_OUT); diff --git a/Kernel/platform/platform-rpipico/mangle.h b/Kernel/platform/platform-rpipico/mangle.h index a8d3aafe56..4cd125a99a 100644 --- a/Kernel/platform/platform-rpipico/mangle.h +++ b/Kernel/platform/platform-rpipico/mangle.h @@ -3,11 +3,13 @@ #define _read f_read #define _write f_write #define _sbrk f_sbrk + #define ssize_t _ssize_t #else #undef panic #undef _read #undef _write #undef _sbrk + #undef ssize_t #endif #undef MANGLED diff --git a/Kernel/platform/platform-rpipico/misc.c b/Kernel/platform/platform-rpipico/misc.c index 5be807aac9..5fdd44fe4c 100644 --- a/Kernel/platform/platform-rpipico/misc.c +++ b/Kernel/platform/platform-rpipico/misc.c @@ -28,9 +28,9 @@ void plt_reboot(void) void plt_monitor(void) { - sleep_ms(1); // wait to print any remaining messages multicore_reset_core1(); - for(;;) { sleep_until(at_the_end_of_time); } + for(;;) + tight_loop_contents(); } uaddr_t pagemap_base(void) diff --git a/Kernel/platform/platform-rpipico/picosdk.h b/Kernel/platform/platform-rpipico/picosdk.h index 0aba57b8fa..55249266e4 100644 --- a/Kernel/platform/platform-rpipico/picosdk.h +++ b/Kernel/platform/platform-rpipico/picosdk.h @@ -1,7 +1,9 @@ #define MANGLED 0 #include "mangle.h" -#include "pico/stdlib.h" +#include +#include +#include #define MANGLED 1 #include "mangle.h" diff --git a/Kernel/platform/platform-rpipico/rawflash.c b/Kernel/platform/platform-rpipico/rawflash.c index 72db1ba091..a416cb1565 100644 --- a/Kernel/platform/platform-rpipico/rawflash.c +++ b/Kernel/platform/platform-rpipico/rawflash.c @@ -1,17 +1,27 @@ +#include +#include "config.h" + +#ifndef PICO_DISABLE_FLASH + #include #include -#include #include "lib/dhara/nand.h" #include "picosdk.h" #include #include "globals.h" +int erase_cycles; +int program_cycles; +int fssync_cycles; +int fswrite_cycles; + int dhara_nand_erase(const struct dhara_nand *n, dhara_block_t b, dhara_error_t *err) { irqflags_t f = di(); flash_range_erase(FLASH_OFFSET + (b*4096), 4096); irqrestore(f); + erase_cycles++; if (err) *err = DHARA_E_NONE; return 0; @@ -24,6 +34,7 @@ int dhara_nand_prog(const struct dhara_nand *n, dhara_page_t p, irqflags_t f = di(); flash_range_program(FLASH_OFFSET + (p*512), data, 512); irqrestore(f); + program_cycles++; if (err) *err = DHARA_E_NONE; return 0; @@ -44,3 +55,4 @@ int dhara_nand_read(const struct dhara_nand *n, dhara_page_t p, /* vim: sw=4 ts=4 et: */ +#endif \ No newline at end of file diff --git a/Kernel/platform/platform-rpipico/rawuart.c b/Kernel/platform/platform-rpipico/rawuart.c new file mode 100644 index 0000000000..f912fece1e --- /dev/null +++ b/Kernel/platform/platform-rpipico/rawuart.c @@ -0,0 +1,47 @@ +#include +#include "picosdk.h" +#include "config.h" +#include "core1.h" + +#include +#include +#include +#include +#include +#include "rawuart.h" + +#if NUM_DEV_TTY_UART != 1 +#error "Only one UART is currently supported" +#endif + +void uart1_init() +{ + uart_init(uart_default, PICO_DEFAULT_UART_BAUD_RATE); + gpio_set_function(PICO_DEFAULT_UART_TX_PIN, GPIO_FUNC_UART); + gpio_set_function(PICO_DEFAULT_UART_RX_PIN, GPIO_FUNC_UART); + uart_set_translate_crlf(uart_default, false); + uart_set_fifo_enabled(uart_default, true); +} + +void uart1_putc(uint8_t c) +{ + while (!uart_is_writable(uart_default)) + { + tight_loop_contents(); + } + uart_putc(uart_default, c); +} + +int uart1_ready() +{ + return uart_is_writable(uart_default); +} + +int uart1_getc() +{ + if (uart_is_readable(uart_default)) + { + return (int)uart_get_hw(uart_default)->dr; + } + return -1; +} \ No newline at end of file diff --git a/Kernel/platform/platform-rpipico/rawuart.h b/Kernel/platform/platform-rpipico/rawuart.h new file mode 100644 index 0000000000..b0a6cbd7e0 --- /dev/null +++ b/Kernel/platform/platform-rpipico/rawuart.h @@ -0,0 +1,9 @@ +#ifndef RAWUART_H +#define RAWUART_H + +extern void uart1_init(); +extern void uart1_putc(uint8_t c); +extern int uart1_ready(); +extern int uart1_getc(); + +#endif \ No newline at end of file diff --git a/Kernel/platform/platform-rpipico/swapper.c b/Kernel/platform/platform-rpipico/swapper.c index 2f736c8426..014ccfafea 100644 --- a/Kernel/platform/platform-rpipico/swapper.c +++ b/Kernel/platform/platform-rpipico/swapper.c @@ -18,7 +18,7 @@ #define BLOCKSIZE 4096 #define NUM_ALLOCATION_BLOCKS (USERMEM / BLOCKSIZE) -uint8_t progbase[USERMEM]; +char progbase[USERMEM]; struct mapentry { diff --git a/Kernel/platform/platform-rpipico/tusb_config.h b/Kernel/platform/platform-rpipico/tusb_config.h index 725c2843d6..00be86eb53 100644 --- a/Kernel/platform/platform-rpipico/tusb_config.h +++ b/Kernel/platform/platform-rpipico/tusb_config.h @@ -3,7 +3,7 @@ #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE) -#define CFG_TUD_CDC (1) +#define CFG_TUD_CDC (4) #define CFG_TUD_CDC_RX_BUFSIZE (64) #define CFG_TUD_CDC_TX_BUFSIZE (64) diff --git a/Kernel/platform/platform-rpipico/update-flash.sh b/Kernel/platform/platform-rpipico/update-flash.sh index 4c91a5fd73..8e5de9e569 100755 --- a/Kernel/platform/platform-rpipico/update-flash.sh +++ b/Kernel/platform/platform-rpipico/update-flash.sh @@ -3,8 +3,14 @@ set -e IMG=filesystem.img +FSSIZE=2547 + +if [ "$1" = "sd" ]; then + FSSIZE=65535 +fi + rm -f ${IMG} -../../../Standalone/mkfs ${IMG} 32 2547 +../../../Standalone/mkfs ${IMG} 32 $FSSIZE ../../../Standalone/ucp ${IMG} <= 2 + TUD_CDC_DESCRIPTOR(USBD_ITF_CDC+2, USBD_STR_CDC, USBD_CDC_EP_CMD+2, + USBD_CDC_CMD_MAX_SIZE, USBD_CDC_EP_OUT+2, USBD_CDC_EP_IN+2, USBD_CDC_IN_OUT_MAX_SIZE), +#endif + +#if CFG_TUD_CDC >= 3 + TUD_CDC_DESCRIPTOR(USBD_ITF_CDC+4, USBD_STR_CDC, USBD_CDC_EP_CMD+4, + USBD_CDC_CMD_MAX_SIZE, USBD_CDC_EP_OUT+4, USBD_CDC_EP_IN+4, USBD_CDC_IN_OUT_MAX_SIZE), +#endif + +#if CFG_TUD_CDC >= 4 + TUD_CDC_DESCRIPTOR(USBD_ITF_CDC+6, USBD_STR_CDC, USBD_CDC_EP_CMD+6, + USBD_CDC_CMD_MAX_SIZE, USBD_CDC_EP_OUT+6, USBD_CDC_EP_IN+6, USBD_CDC_IN_OUT_MAX_SIZE), +#endif }; static const char *const usbd_desc_str[] = { diff --git a/Kernel/platform/platform-rpipico/utils/Makefile b/Kernel/platform/platform-rpipico/utils/Makefile new file mode 100644 index 0000000000..b9e0fb4327 --- /dev/null +++ b/Kernel/platform/platform-rpipico/utils/Makefile @@ -0,0 +1,33 @@ +ROOT=../../../.. +FUZIX_ROOT=$(ROOT) +USERCPU=armm0 +VERBOSE=1 +include $(FUZIX_ROOT)/Target/rules.$(USERCPU) + + +UTILS = ps.c +UTILSO = $(UTILS:.c=.o) +UTILSBIN = $(UTILS:.c=) + +.PHONY: all clean + +all: $(UTILSBIN) + +clean: + rm -f *.o + rm -f $(UTILSBIN) + rm -f progbase.h + rm -f ps.c + +$(UTILSBIN): %: %.o + $(LINKER) $(CRT0) $^ -o $@ $(LINKER_OPT) $(LINKER_TAIL) + +ps.c: + cp ../../../../Applications/util/ps.c . + +%.o: %.c progbase.h + $(CC) $(CFLAGS) $(CCOPTS) -c $< + +progbase.h: + nm ../build/fuzix.elf | grep progbase | awk '{print "#define PROGBASE 0x" $$1}' > progbase.h + diff --git a/Kernel/platform/platform-rpipico/utils/pico b/Kernel/platform/platform-rpipico/utils/pico new file mode 100644 index 0000000000..ddbd65c611 --- /dev/null +++ b/Kernel/platform/platform-rpipico/utils/pico @@ -0,0 +1,17 @@ +if { test $# -eq 0 || test "$1" = "--help"; }; then + echo -e "\ +usage: $0 [ --help ] \n\ +Command list:\n\ +\tflash\tUnmount filesystem and reboot into flash mode." +else + case $1 in + flash) + killall + umount -a + substroot remount % ro + echo "Rebooting into flash mode" + echo "f" > /dev/pico + ;; + *) echo "Invalid command. Use --help to list available options." ;; + esac +fi \ No newline at end of file diff --git a/Kernel/platform/platform-rpipico/utils/ps-rpipico.patch b/Kernel/platform/platform-rpipico/utils/ps-rpipico.patch new file mode 100644 index 0000000000..6902fb953e --- /dev/null +++ b/Kernel/platform/platform-rpipico/utils/ps-rpipico.patch @@ -0,0 +1,33 @@ +--- ../../../../Applications/util/ps.c 2024-02-12 16:06:26.445511000 -0700 ++++ ps.c 2024-03-31 10:58:57.708871714 -0600 +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include "progbase.h" + + #define TTY_MAJOR 2 /* Be nice if we didn't have to + just know this */ +@@ -66,6 +67,9 @@ + #define OF_TIME 8192 /* Cumulative execution time */ + #define OF_CMD 16384 /* Command line */ + ++#define BLOCKSIZE 4096 ++#define alignup(v,a) (uint8_t*)((intptr_t)((v) + (a)-1) & ~((a)-1)) ++ + static const char *month = "JanFebMarAprMayJunJulAugSepOctNovDec"; + + static char mapstat(char s) +@@ -348,7 +352,11 @@ + if (outflags & OF_ADDR) + fputs(" - ", stdout); + if (outflags & OF_SZ) +- fputs(" - ", stdout); ++ { ++ long size = pp->p_top - PROGBASE; ++ size = (long)alignup(size, BLOCKSIZE) / BLOCKSIZE; ++ printf("%5d ", size); ++ } + if (outflags & OF_WCHAN) { + if (pp->p_status > 2) + printf(" %4x ", (unsigned int)pp->p_wait); diff --git a/Kernel/tools/makeversion.c b/Kernel/tools/makeversion.c index 85c4a22ea4..bd2e99aafe 100644 --- a/Kernel/tools/makeversion.c +++ b/Kernel/tools/makeversion.c @@ -2,6 +2,11 @@ #include #include +/* Not sure why utsname.h needs + * I'm keeping it but disable it here */ +#define __TYPES_H +#include "../../Library/include/utsname.h" + void write_body(FILE *out, char *v, char *sv, char *p) { @@ -65,6 +70,15 @@ struct sysinfoblk {\n\ \n", (int)(strlen(v) + strlen(sv) + strlen(p) + 9)); } +void trimstr(char* str, int size) { + while(*str && size--) { + *str++; + } + *str = '\0'; +} + +#define member_size(type, member) (sizeof(((type*)0)->member)) + int main(int argc, char *argv[]) { FILE *f; @@ -77,6 +91,11 @@ int main(int argc, char *argv[]) perror("include/sysinfoblk.h"); exit(1); } + + trimstr(argv[1], member_size(struct utsname, release)); + trimstr(argv[2], member_size(struct utsname, version)); + trimstr(argv[3], member_size(struct utsname, machine)); + write_header(f, argv[1], argv[2], argv[3]); fclose(f); f = fopen("version.c", "w");