Compare commits

...

9 Commits

Author SHA1 Message Date
mwojcik 1c8e2c318c eth phy: reset page to 0 on kasli-soc for ident 2022-03-10 17:11:41 +08:00
mwojcik 67880b4e0b openocd: moved common code from target files 2022-03-10 17:05:25 +08:00
Sebastien Bourdeauducq e96222ff6f update dependencies 2022-03-10 17:01:37 +08:00
mwojcik dc1ca3d3d0 szl: fallback to netboot if boot mode not supported 2022-03-10 16:48:00 +08:00
mwojcik c4c52c33b4 eth phy: use unreachable!() for impossible values 2022-03-10 16:45:29 +08:00
mwojcik 072fd5f015 eth phy: set LEDs only on Kasli-SoC 2022-03-10 16:42:25 +08:00
mwojcik 2b3c7e4b2f eth leds:
* break led0 from led1 - similar, but not the same settings (led2 not implemented)
* fix values, make it compilable
* set default behavior (one led for link, other for activity)
2022-03-10 16:42:25 +08:00
mwojcik 84d6d391ce libboard_zynq: eth phy for Marvell 88E1518
* add support for LED control registers
* support for registers on different pages
2022-03-10 16:42:25 +08:00
mwojcik 43e0440911 Kasli-SoC: Get MAC address from EEPROM (#90)
Co-authored-by: mwojcik <mw@m-labs.hk>
Co-committed-by: mwojcik <mw@m-labs.hk>
2022-03-07 18:01:44 +08:00
18 changed files with 223 additions and 99 deletions

16
Cargo.lock generated
View File

@ -8,9 +8,9 @@ checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4"
[[package]]
name = "bitflags"
version = "1.2.1"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "byteorder"
@ -20,9 +20,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "cc"
version = "1.0.69"
version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
[[package]]
name = "cfg-if"
@ -47,9 +47,9 @@ dependencies = [
[[package]]
name = "embedded-hal"
version = "0.2.6"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e36cfb62ff156596c892272f3015ef952fe1525e85261fa3a7f327bd6b384ab9"
checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff"
dependencies = [
"nb 0.1.3",
"void",
@ -250,9 +250,9 @@ checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
[[package]]
name = "volatile-register"
version = "0.2.0"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d67cb4616d99b940db1d6bd28844ff97108b498a6ca850e5b6191a532063286"
checksum = "9ee8f19f9d74293faf70901bc20ad067dc1ad390d2cbf1e3f75f721ffee908b6"
dependencies = [
"vcell",
]

View File

@ -14,7 +14,7 @@ members = [
panic = "abort"
debug = true
codegen-units = 1
opt-level = 'z'
opt-level = 's'
lto = true
debug-assertions = false
overflow-checks = false

View File

@ -3,11 +3,11 @@
"mozilla-overlay": {
"flake": false,
"locked": {
"lastModified": 1638887313,
"narHash": "sha256-FMYV6rVtvSIfthgC1sK1xugh3y7muoQcvduMdriz4ag=",
"lastModified": 1645464064,
"narHash": "sha256-YeN4bpPvHkVOpQzb8APTAfE7/R+MFMwJUMkqmfvytSk=",
"owner": "mozilla",
"repo": "nixpkgs-mozilla",
"rev": "7c1e8b1dd6ed0043fb4ee0b12b815256b0b9de6f",
"rev": "15b7a05f20aab51c4ffbefddb1b448e862dccb7d",
"type": "github"
},
"original": {
@ -18,11 +18,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1642961095,
"narHash": "sha256-RLatktZmvwFBOyqdoIk4qdS4OGKB7aKIvvs4ZP2L8D8=",
"lastModified": 1646588256,
"narHash": "sha256-ZHljmNlt19nSm0Mz8fx6QEhddKUkU4hhwFmfNmGn+EY=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "604c44137d97b5111be1ca5c0d97f6e24fbc5c2c",
"rev": "2ebb6c1e5ae402ba35cca5eec58385e5f1adea04",
"type": "github"
},
"original": {

View File

@ -310,6 +310,8 @@ impl<GEM: Gem> Eth<GEM, (), ()> {
let phy = Phy::find(&mut inner).expect("phy");
phy.reset(&mut inner);
phy.restart_autoneg(&mut inner);
#[cfg(feature="target_kasli_soc")]
phy.set_leds(&mut inner);
Eth {
rx: (),

View File

@ -82,6 +82,10 @@ impl PhyRegister for Control {
fn addr() -> u8 {
0
}
fn page() -> u8 {
0
}
}
impl From<u16> for Control {

View File

@ -11,6 +11,9 @@ pub struct PhyIdentifier {
}
pub fn identify_phy<PA: PhyAccess>(pa: &mut PA, addr: u8) -> Option<PhyIdentifier> {
#[cfg(feature = "target_kasli_soc")]
pa.write_phy(addr, 0x16, 0); //reset page
let id1 = pa.read_phy(addr, 2);
let id2 = pa.read_phy(addr, 3);
if id1 != 0xFFFF || id2 != 0xFFFF {

View File

@ -0,0 +1,79 @@
use bit_field::BitField;
use super::{PhyRegister, Led0Control, Led1Control};
#[derive(Clone, Copy, Debug)]
/// LED Control Register
pub struct Leds(pub u16);
impl Leds {
pub fn led0(&self) -> Led0Control {
match self.0.get_bits(0..=3) {
0b0000 => Led0Control::OnLinkOffNoLink,
0b0001 => Led0Control::OnLinkBlinkActivityOffNoLink,
0b0010 => Led0Control::BlinkDependingOnLink,
0b0011 => Led0Control::OnActivityOffNoActivity,
0b0100 => Led0Control::BlinkActivityOffNoActivity,
0b0101 => Led0Control::OnTransmitOffNoTransmit,
0b0110 => Led0Control::OnCopperLinkOffElse,
0b0111 => Led0Control::On1000LinkOffElse,
0b1000 => Led0Control::ForceOff,
0b1001 => Led0Control::ForceOn,
0b1010 => Led0Control::ForceHiZ,
0b1011 => Led0Control::ForceBlink,
0b1100 => Led0Control::Mode1,
0b1101 => Led0Control::Mode2,
0b1110 => Led0Control::Mode3,
0b1111 => Led0Control::Mode4,
_ => unreachable!()
}
}
pub fn led1(&self) -> Led1Control {
match self.0.get_bits(4..=7) {
0b0000 => Led1Control::OnReceiveOffNoReceive,
0b0001 => Led1Control::OnLinkBlinkActivityOffNoLink,
0b0010 => Led1Control::OnLinkBlinkReceiveOffNoLink,
0b0011 => Led1Control::OnActivityOffNoActivity,
0b0100 => Led1Control::BlinkActivityOffNoActivity,
0b0101 => Led1Control::On100OrFiberOffElse,
0b0110 => Led1Control::On1001000LinkOffElse,
0b0111 => Led1Control::On100LinkOffElse,
0b1000 => Led1Control::ForceOff,
0b1001 => Led1Control::ForceOn,
0b1010 => Led1Control::ForceHiZ,
0b1011 => Led1Control::ForceBlink,
_ => unreachable!()
}
}
pub fn set_led0(mut self, setting: Led0Control) -> Self {
self.0.set_bits(0..=3, setting as u16);
self
}
pub fn set_led1(mut self, setting: Led1Control) -> Self {
self.0.set_bits(4..=7, setting as u16);
self
}
}
impl PhyRegister for Leds {
fn addr() -> u8 {
0x10
}
fn page() -> u8 {
3
}
}
impl From<u16> for Leds {
fn from(value: u16) -> Self {
Leds(value)
}
}
impl Into<u16> for Leds {
fn into(self) -> u16 {
self.0
}
}

View File

@ -6,6 +6,8 @@ mod control;
pub use control::Control;
mod pssr;
pub use pssr::PSSR;
mod leds;
pub use leds::Leds;
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Link {
@ -26,6 +28,42 @@ pub enum LinkDuplex {
Full,
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Led0Control {
OnLinkOffNoLink = 0b0000,
OnLinkBlinkActivityOffNoLink = 0b0001,
BlinkDependingOnLink = 0b0010,
OnActivityOffNoActivity = 0b0011,
BlinkActivityOffNoActivity = 0b0100,
OnTransmitOffNoTransmit = 0b0101,
OnCopperLinkOffElse = 0b0110,
On1000LinkOffElse = 0b0111,
ForceOff = 0b1000,
ForceOn = 0b1001,
ForceHiZ = 0b1010,
ForceBlink = 0b1011,
Mode1 = 0b1100,
Mode2 = 0b1101,
Mode3 = 0b1110,
Mode4 = 0b1111
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Led1Control {
OnReceiveOffNoReceive = 0b0000,
OnLinkBlinkActivityOffNoLink = 0b0001,
OnLinkBlinkReceiveOffNoLink = 0b0010,
OnActivityOffNoActivity = 0b0011,
BlinkActivityOffNoActivity = 0b0100,
On100OrFiberOffElse = 0b0101,
On1001000LinkOffElse = 0b0110,
On100LinkOffElse = 0b0111,
ForceOff = 0b1000,
ForceOn = 0b1001,
ForceHiZ = 0b1010,
ForceBlink = 0b1011,
}
pub trait PhyAccess {
fn read_phy(&mut self, addr: u8, reg: u8) -> u16;
fn write_phy(&mut self, addr: u8, reg: u8, data: u16);
@ -33,6 +71,7 @@ pub trait PhyAccess {
pub trait PhyRegister {
fn addr() -> u8;
fn page() -> u8;
}
@ -45,6 +84,10 @@ const OUI_MARVELL: u32 = 0x005043;
const OUI_REALTEK: u32 = 0x000732;
const OUI_LANTIQ : u32 = 0x355969;
//only change pages on Kasli-SoC's Marvel 88E11xx
#[cfg(feature="target_kasli_soc")]
const PAGE_REGISTER: u8 = 0x16;
impl Phy {
/// Probe all addresses on MDIO for a known PHY
pub fn find<PA: PhyAccess>(pa: &mut PA) -> Option<Phy> {
@ -84,6 +127,9 @@ impl Phy {
PA: PhyAccess,
PR: PhyRegister + From<u16>,
{
#[cfg(feature="target_kasli_soc")]
pa.write_phy(self.addr, PAGE_REGISTER, PR::page().into());
pa.read_phy(self.addr, PR::addr()).into()
}
@ -93,6 +139,9 @@ impl Phy {
PR: PhyRegister + From<u16> + Into<u16>,
F: FnMut(PR) -> PR,
{
#[cfg(feature="target_kasli_soc")]
pa.write_phy(self.addr, PAGE_REGISTER, PR::page().into());
let reg = pa.read_phy(self.addr, PR::addr()).into();
let reg = f(reg);
pa.write_phy(self.addr, PR::addr(), reg.into())
@ -106,6 +155,14 @@ impl Phy {
self.modify_reg(pa, f)
}
pub fn modify_leds<PA, F>(&self, pa: &mut PA, f: F)
where
PA: PhyAccess,
F: FnMut(Leds) -> Leds,
{
self.modify_reg(pa, f)
}
pub fn get_control<PA: PhyAccess>(&self, pa: &mut PA) -> Control {
self.read_reg(pa)
}
@ -139,4 +196,12 @@ impl Phy {
.set_restart_autoneg(true)
);
}
#[cfg(feature="target_kasli_soc")]
pub fn set_leds<PA: PhyAccess>(&self, pa: &mut PA) {
self.modify_leds(pa, |leds|
leds.set_led0(Led0Control::OnCopperLinkOffElse)
.set_led1(Led1Control::BlinkActivityOffNoActivity)
);
}
}

View File

@ -43,6 +43,10 @@ impl PhyRegister for PSSR {
fn addr() -> u8 {
0x11
}
fn page() -> u8 {
0
}
}
impl From<u16> for PSSR {

View File

@ -100,6 +100,10 @@ impl PhyRegister for Status {
fn addr() -> u8 {
1
}
fn page() -> u8 {
0
}
}
impl From<u16> for Status {

View File

@ -30,7 +30,19 @@ impl fmt::Display for NetAddresses {
}
}
pub fn get_adresses(cfg: &Config) -> NetAddresses {
#[cfg(feature = "target_kasli_soc")]
fn get_address_from_eeprom() -> EthernetAddress {
use libboard_zynq::i2c::{I2c, eeprom};
let mut i2c = I2c::i2c0();
i2c.init().unwrap();
let mut eeprom = eeprom::EEPROM::new(&mut i2c, 16);
let address = eeprom.read_eui48().unwrap_or([0x02, 0x00, 0x00, 0x00, 0x00, 0x56]);
EthernetAddress(address)
}
pub fn get_addresses(cfg: &Config) -> NetAddresses {
#[cfg(feature = "target_zc706")]
let mut hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x52]);
#[cfg(feature = "target_zc706")]
@ -44,7 +56,7 @@ pub fn get_adresses(cfg: &Config) -> NetAddresses {
#[cfg(feature = "target_redpitaya")]
let mut ipv4_addr = IpAddress::v4(192, 168, 1, 55);
#[cfg(feature = "target_kasli_soc")]
let mut hardware_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x56]);
let mut hardware_addr = get_address_from_eeprom();
#[cfg(feature = "target_kasli_soc")]
let mut ipv4_addr = IpAddress::v4(192, 168, 1, 56);

20
openocd/common.cfg Normal file
View File

@ -0,0 +1,20 @@
set XC7_JSHUTDOWN 0x0d
set XC7_JPROGRAM 0x0b
set XC7_JSTART 0x0c
set XC7_BYPASS 0x3f
proc xc7_program {tap} {
global XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS
irscan $tap $XC7_JSHUTDOWN
irscan $tap $XC7_JPROGRAM
runtest 60000
#JSTART prevents this from working...
#irscan $tap $XC7_JSTART
runtest 2000
irscan $tap $XC7_BYPASS
runtest 2000
}
pld device virtex2 zynq.tap 1
init
xc7_program zynq.tap

View File

@ -8,26 +8,7 @@ source ./zynq-7000.cfg
reset_config srst_only srst_push_pull
set XC7_JSHUTDOWN 0x0d
set XC7_JPROGRAM 0x0b
set XC7_JSTART 0x0c
set XC7_BYPASS 0x3f
proc xc7_program {tap} {
global XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS
irscan $tap $XC7_JSHUTDOWN
irscan $tap $XC7_JPROGRAM
runtest 60000
#JSTART prevents this from working...
#irscan $tap $XC7_JSTART
runtest 2000
irscan $tap $XC7_BYPASS
runtest 2000
}
pld device virtex2 zynq.tap 1
init
xc7_program zynq.tap
source ./common.cfg
reset halt

View File

@ -17,26 +17,7 @@ reset_config srst_only srst_open_drain
adapter srst pulse_width 250
adapter srst delay 400
set XC7_JSHUTDOWN 0x0d
set XC7_JPROGRAM 0x0b
set XC7_JSTART 0x0c
set XC7_BYPASS 0x3f
proc xc7_program {tap} {
global XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS
irscan $tap $XC7_JSHUTDOWN
irscan $tap $XC7_JPROGRAM
runtest 60000
#JSTART prevents this from working...
#irscan $tap $XC7_JSTART
runtest 2000
irscan $tap $XC7_BYPASS
runtest 2000
}
pld device virtex2 zynq.tap 1
init
xc7_program zynq.tap
source ./common.cfg
reset halt

View File

@ -8,26 +8,7 @@ source ./zynq-7000.cfg
reset_config none
set XC7_JSHUTDOWN 0x0d
set XC7_JPROGRAM 0x0b
set XC7_JSTART 0x0c
set XC7_BYPASS 0x3f
proc xc7_program {tap} {
global XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS
irscan $tap $XC7_JSHUTDOWN
irscan $tap $XC7_JPROGRAM
runtest 60000
#JSTART prevents this from working...
#irscan $tap $XC7_JSTART
runtest 2000
irscan $tap $XC7_BYPASS
runtest 2000
}
pld device virtex2 zynq.tap 1
init
xc7_program zynq.tap
source ./common.cfg
halt

View File

@ -10,26 +10,7 @@ reset_config srst_only srst_open_drain
adapter srst pulse_width 250
adapter srst delay 400
set XC7_JSHUTDOWN 0x0d
set XC7_JPROGRAM 0x0b
set XC7_JSTART 0x0c
set XC7_BYPASS 0x3f
proc xc7_program {tap} {
global XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS
irscan $tap $XC7_JSHUTDOWN
irscan $tap $XC7_JPROGRAM
runtest 60000
#JSTART prevents this from working...
#irscan $tap $XC7_JSTART
runtest 2000
irscan $tap $XC7_BYPASS
runtest 2000
}
pld device virtex2 zynq.tap 1
init
xc7_program zynq.tap
source ./common.cfg
reset halt

View File

@ -136,7 +136,14 @@ pub fn main_core0() {
}
}
v => {
panic!("Boot mode {:?} not supported", v);
log::error!("Boot mode {:?} not supported", v);
log::info!("Fall back on netboot");
netboot::netboot(
&mut bootgen_file,
config,
&mut __runtime_start as *mut usize as *mut u8,
max_len,
)
}
};
}

View File

@ -316,7 +316,7 @@ pub fn netboot<File: Read + Seek>(
runtime_max_len: usize,
) {
log::info!("Preparing network for netboot");
let net_addresses = net_settings::get_adresses(&cfg);
let net_addresses = net_settings::get_addresses(&cfg);
log::info!("Network addresses: {}", net_addresses);
let eth = Eth::eth0(net_addresses.hardware_addr.0.clone());
let eth = eth.start_rx(8);