diff --git a/src/main.rs b/src/main.rs index 346ce973..896cd609 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,13 +10,14 @@ #![allow(dead_code)] extern crate alloc; + use alloc::{vec, vec::Vec}; use core::mem::transmute; -use compiler_builtins as _; use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr}; use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder}; use smoltcp::time::Instant; use smoltcp::socket::SocketSet; +use smoltcp::socket::{TcpSocket, TcpSocketBuffer}; mod boot; mod regs; @@ -26,11 +27,17 @@ mod panic; mod zynq; mod stdio; mod ram; +use cortex_a9::mutex::Mutex; const HWADDR: [u8; 6] = [0, 0x23, 0xde, 0xea, 0xbe, 0xef]; +static mut STACK_CORE1: [u32; 512] = [0; 512]; + pub fn main() { + // zynq::clocks::CpuClocks::enable_io(1_250_000_000); println!("\nzc706 main"); + use regs::RegisterR; + println!("Boot mode: {:?}", zynq::slcr::RegisterBlock::new().boot_mode.read().boot_mode_pins()); let mut flash = zynq::flash::Flash::new(200_000_000).linear_addressing_mode(); let flash_ram: &[u8] = unsafe { core::slice::from_raw_parts(flash.ptr(), flash.size()) }; @@ -44,30 +51,71 @@ pub fn main() { let mut flash = flash.stop(); let mut ddr = zynq::ddr::DdrRam::new(); - println!("DDR: {:?}", ddr.status()); + #[cfg(not(feature = "target_zc706"))] ddr.memtest(); ram::init_alloc(&mut ddr); for i in 0..=1 { let mut flash_io = flash.manual_mode(i); + // println!("rdcr={:02X}", flash_io.rdcr()); print!("Flash {} ID:", i); for b in flash_io.rdid() { print!(" {:02X}", b); } println!(""); print!("Flash {} I/O:", i); - for o in 0..4 { - for b in flash_io.read(32 * o, 32) { + for o in 0..8 { + const CHUNK: u32 = 8; + for b in flash_io.read(CHUNK * o, CHUNK as usize) { print!(" {:02X}", b); } } println!(""); + + flash_io.dump("Read cr1", 0x35); + flash_io.dump("Read Autoboot", 0x14); + flash_io.dump("Read Bank", 0x16); + flash_io.dump("DLP Bank", 0x16); + flash_io.dump("Read ESig", 0xAB); + flash_io.dump("OTP Read", 0x4B); + flash_io.dump("DYB Read", 0xE0); + flash_io.dump("PPB Read", 0xE2); + flash_io.dump("ASP Read", 0x2B); + flash_io.dump("Password Read", 0xE7); + + flash_io.write_enabled(|flash_io| { + flash_io.erase(0); + }); + flash_io.write_enabled(|flash_io| { + flash_io.program(0, [0x23054223; (0x100 >> 2)].iter().cloned()); + }); + flash = flash_io.stop(); } - - let core1_stack = vec![0; 2048]; + + let core1_stack = unsafe { &mut STACK_CORE1[..] }; println!("{} bytes stack for core1", core1_stack.len()); - boot::Core1::start(core1_stack); + let core1 = boot::Core1::start(core1_stack); + + for _ in 0..0x1000000 { + let mut l = SHARED.lock(); + *l += 1; + } + while !*DONE.lock() { + let x = { *SHARED.lock() }; + println!("shared: {:08X}", x); + } + let x = { *SHARED.lock() }; + println!("done shared: {:08X}", x); + + core1.stop(); + + cortex_a9::asm::dsb(); + print!("Core1 stack [{:08X}..{:08X}]:", &core1.stack[0] as *const _ as u32, &core1.stack[core1.stack.len() - 1] as *const _ as u32); + for w in core1.stack { + print!(" {:08X}", w); + } + println!("."); let eth = zynq::eth::Eth::default(HWADDR.clone()); println!("Eth on"); @@ -109,6 +157,16 @@ pub fn main() { ]; let mut sockets = SocketSet::new(&mut sockets_storage[..]); + // taken from example code for smoltcp + let mut tcp_server_rx_data = vec![0; 512 * 1024]; + let mut tcp_server_tx_data = vec![0; 512 * 1024]; + let tcp_rx_buffer = TcpSocketBuffer::new(&mut tcp_server_rx_data[..]); + let tcp_tx_buffer = TcpSocketBuffer::new(&mut tcp_server_tx_data[..]); + let tcp_socket = TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer); + let tcp_handle = sockets.add(tcp_socket); + /// `chargen` + const TCP_PORT: u16 = 19; + let mut time = 0u32; loop { time += 1; @@ -121,36 +179,41 @@ pub fn main() { } } - // match eth.recv_next() { - // Ok(Some(pkt)) => { - // print!("eth: rx {} bytes", pkt.len()); - // for b in pkt.iter() { - // print!(" {:02X}", b); - // } - // println!(""); - // } - // Ok(None) => {} - // Err(e) => { - // println!("eth rx error: {:?}", e); - // } - // } + // (mostly) taken from smoltcp example: TCP echo server + let mut socket = sockets.get::(tcp_handle); + if !socket.is_open() { + socket.listen(TCP_PORT).unwrap() + } + if socket.may_recv() && socket.can_send() { + socket.recv(|buf| { + let len = buf.len().min(4096); + let buffer = buf[..len].iter().cloned().collect::>(); + (len, buffer) + }) + .and_then(|buffer| socket.send_slice(&buffer[..])) + .map(|_| {}) + .unwrap_or_else(|e| println!("tcp: {:?}", e)); - // match eth.send(512) { - // Some(mut pkt) => { - // let mut x = 0; - // for b in pkt.iter_mut() { - // *b = x; - // x += 1; - // } - // println!("eth tx {} bytes", pkt.len()); - // } - // None => println!("eth tx shortage"), - // } + } } + // #[allow(unreachable_code)] + // drop(tx_descs); + // #[allow(unreachable_code)] + // drop(tx_buffers); } +static SHARED: Mutex = Mutex::new(0); +static DONE: Mutex = Mutex::new(false); + pub fn main_core1() { println!("Hello from core1!"); + for _ in 0..0x1000000 { + let mut l = SHARED.lock(); + *l += 1; + } + println!("core1 done!"); + *DONE.lock() = true; + loop {} } diff --git a/src/zynq/flash/mod.rs b/src/zynq/flash/mod.rs index 5bb8ab90..f93cdfe9 100644 --- a/src/zynq/flash/mod.rs +++ b/src/zynq/flash/mod.rs @@ -494,3 +494,13 @@ impl Flash { Transfer::new(self, args, len) } + pub fn dump(&mut self, label: &'_ str, inst_code: u8) { + print!("{}:", label); + + let args = Some(u32::from(inst_code) << 24); + for b in self.transfer(args.into_iter(), 32).bytes_transfer() { + print!(" {:02X}", b); + } + println!(""); + } +}