diff --git a/runtime/src/main.rs b/runtime/src/main.rs index f56043b2..2c9168ce 100644 --- a/runtime/src/main.rs +++ b/runtime/src/main.rs @@ -4,23 +4,16 @@ extern crate alloc; use core::{cmp, str}; -use core::mem::transmute; use libboard_zynq::{ println, self as zynq, clocks::Clocks, clocks::source::{ClockSource, ArmPll, IoPll}, - smoltcp::{ - wire::{EthernetAddress, IpAddress, IpCidr}, - iface::{NeighborCache, EthernetInterfaceBuilder, Routes}, - time::Instant, - }, }; -use libsupport_zynq::{ - ram, alloc::{vec, vec::Vec}, -}; -use libasync::smoltcp::Sockets; +use libsupport_zynq::ram; + mod pl; +mod network; fn identifier_read(buf: &mut [u8]) -> &str { unsafe { @@ -35,8 +28,6 @@ fn identifier_read(buf: &mut [u8]) -> &str { } } -const HWADDR: [u8; 6] = [0, 0x23, 0xab, 0xad, 0x1d, 0xea]; - #[no_mangle] pub fn main_core0() { println!("ARTIQ runtime starting..."); @@ -46,52 +37,13 @@ pub fn main_core0() { ArmPll::setup(2 * CPU_FREQ); Clocks::set_cpu_freq(CPU_FREQ); IoPll::setup(1_000_000_000); - libboard_zynq::stdio::drop_uart(); // why? + libboard_zynq::stdio::drop_uart(); // reinitialize UART after clocking change let mut ddr = zynq::ddr::DdrRam::new(); ram::init_alloc(&mut ddr); println!("Detected gateware: {}", identifier_read(&mut [0; 64])); - let eth = zynq::eth::Eth::default(HWADDR.clone()); - const RX_LEN: usize = 8; - let mut rx_descs = (0..RX_LEN) - .map(|_| zynq::eth::rx::DescEntry::zeroed()) - .collect::>(); - let mut rx_buffers = vec![zynq::eth::Buffer::new(); RX_LEN]; - // Number of transmission buffers (minimum is two because with - // one, duplicate packet transmission occurs) - const TX_LEN: usize = 8; - let mut tx_descs = (0..TX_LEN) - .map(|_| zynq::eth::tx::DescEntry::zeroed()) - .collect::>(); - let mut tx_buffers = vec![zynq::eth::Buffer::new(); TX_LEN]; - let eth = eth.start_rx(&mut rx_descs, &mut rx_buffers); - let mut eth = eth.start_tx( - // HACK - unsafe { transmute(tx_descs.as_mut_slice()) }, - unsafe { transmute(tx_buffers.as_mut_slice()) }, - ); - let ethernet_addr = EthernetAddress(HWADDR); - - let local_addr = IpAddress::v4(192, 168, 1, 52); - let mut ip_addrs = [IpCidr::new(local_addr, 24)]; - let mut routes_storage = vec![None; 4]; - let routes = Routes::new(&mut routes_storage[..]); - let mut neighbor_storage = vec![None; 256]; - let neighbor_cache = NeighborCache::new(&mut neighbor_storage[..]); - let mut iface = EthernetInterfaceBuilder::new(&mut eth) - .ethernet_addr(ethernet_addr) - .ip_addrs(&mut ip_addrs[..]) - .routes(routes) - .neighbor_cache(neighbor_cache) - .finalize(); - - Sockets::init(32); - let mut time = 0u32; - Sockets::run(&mut iface, || { - time += 1; - Instant::from_millis(time) - }); + network::network_main(); } #[no_mangle] diff --git a/runtime/src/network.rs b/runtime/src/network.rs new file mode 100644 index 00000000..2bde3d2d --- /dev/null +++ b/runtime/src/network.rs @@ -0,0 +1,100 @@ +use core::{mem::transmute, task::Poll}; + +use alloc::{borrow::ToOwned, format}; +use libboard_zynq::{ + println, + self as zynq, + smoltcp::{ + self, + wire::{EthernetAddress, IpAddress, Ipv4Address, IpCidr}, + iface::{NeighborCache, EthernetInterfaceBuilder, Routes}, + time::Instant, + }, +}; +use libsupport_zynq::alloc::{vec, vec::Vec}; + +use libasync::smoltcp::{Sockets, TcpStream}; + + +async fn handle_connection(stream: TcpStream) -> smoltcp::Result<()> { + stream.send("Enter your name: ".bytes()).await?; + let name = stream.recv(|buf| { + for (i, b) in buf.iter().enumerate() { + if *b == '\n' as u8 { + return match core::str::from_utf8(&buf[0..i]) { + Ok(name) => + Poll::Ready((i + 1, Some(name.to_owned()))), + Err(_) => + Poll::Ready((i + 1, None)) + }; + } + } + if buf.len() > 100 { + // Too much input, consume all + Poll::Ready((buf.len(), None)) + } else { + Poll::Pending + } + }).await?; + match name { + Some(name) => + stream.send(format!("Hello {}!\n", name).bytes()).await?, + None => + stream.send("I had trouble reading your name.\n".bytes()).await?, + } + stream.flush().await; + Ok(()) +} + + +const HWADDR: [u8; 6] = [0, 0x23, 0xab, 0xad, 0x1d, 0xea]; +const IPADDR: IpAddress = IpAddress::Ipv4(Ipv4Address([192, 168, 1, 52])); + +pub fn network_main() { + let eth = zynq::eth::Eth::default(HWADDR.clone()); + const RX_LEN: usize = 8; + let mut rx_descs = (0..RX_LEN) + .map(|_| zynq::eth::rx::DescEntry::zeroed()) + .collect::>(); + let mut rx_buffers = vec![zynq::eth::Buffer::new(); RX_LEN]; + // Number of transmission buffers (minimum is two because with + // one, duplicate packet transmission occurs) + const TX_LEN: usize = 8; + let mut tx_descs = (0..TX_LEN) + .map(|_| zynq::eth::tx::DescEntry::zeroed()) + .collect::>(); + let mut tx_buffers = vec![zynq::eth::Buffer::new(); TX_LEN]; + let eth = eth.start_rx(&mut rx_descs, &mut rx_buffers); + let mut eth = eth.start_tx( + // HACK + unsafe { transmute(tx_descs.as_mut_slice()) }, + unsafe { transmute(tx_buffers.as_mut_slice()) }, + ); + let ethernet_addr = EthernetAddress(HWADDR); + + let mut ip_addrs = [IpCidr::new(IPADDR, 24)]; + let mut routes_storage = vec![None; 4]; + let routes = Routes::new(&mut routes_storage[..]); + let mut neighbor_storage = vec![None; 256]; + let neighbor_cache = NeighborCache::new(&mut neighbor_storage[..]); + let mut iface = EthernetInterfaceBuilder::new(&mut eth) + .ethernet_addr(ethernet_addr) + .ip_addrs(&mut ip_addrs[..]) + .routes(routes) + .neighbor_cache(neighbor_cache) + .finalize(); + + Sockets::init(32); + + TcpStream::listen(1381, 2048, 2048, 8, |stream| async { + let _ = handle_connection(stream) + .await + .map_err(|e| println!("Connection: {:?}", e)); + }); + + let mut time = 0u32; + Sockets::run(&mut iface, || { + time += 1; + Instant::from_millis(time) + }); +}