1212// Imports
1313use core:: fmt:: Write ;
1414use neotron_common_bios as bios;
15+ use serde:: { Deserialize , Serialize } ;
1516
1617// ===========================================================================
1718// Global Variables
@@ -184,56 +185,53 @@ impl core::fmt::Write for SerialConsole {
184185 }
185186}
186187
187- // ===========================================================================
188- // Private functions
189- // ===========================================================================
190-
191- /// Initialise our global variables - the BIOS will not have done this for us
192- /// (as it doesn't know where they are).
193- unsafe fn start_up_init ( ) {
194- extern "C" {
195-
196- // These symbols come from `link.x`
197- static mut __sbss: u32 ;
198- static mut __ebss: u32 ;
199-
200- static mut __sdata: u32 ;
201- static mut __edata: u32 ;
202- static __sidata: u32 ;
203- }
204-
205- r0:: zero_bss ( & mut __sbss, & mut __ebss) ;
206- r0:: init_data ( & mut __sdata, & mut __edata, & __sidata) ;
207- }
208-
188+ /// Represents our configuration information that we ask the BIOS to serialise
189+ #[ derive( Debug , Serialize , Deserialize ) ]
209190struct Config {
210- vga_console : bool ,
211- serial_console : bool ,
191+ vga_console_on : bool ,
192+ serial_console_on : bool ,
193+ serial_baud : u32 ,
212194}
213195
214196impl Config {
215- /// Create a new default Config object
216- ///
217- /// TODO: We should load from EEPROM / RTC SRAM here.
218- fn new ( ) -> Config {
219- Config {
220- vga_console : true ,
221- serial_console : true ,
197+ fn load ( ) -> Result < Config , & ' static str > {
198+ if let Some ( api) = unsafe { API } {
199+ let mut buffer = [ 0u8 ; 64 ] ;
200+ match ( api. configuration_get ) ( bios:: ApiBuffer :: new ( & mut buffer) ) {
201+ bios:: Result :: Ok ( n) => {
202+ postcard:: from_bytes ( & buffer[ 0 ..n] ) . map_err ( |_e| "Failed to parse config" )
203+ }
204+ bios:: Result :: Err ( _e) => Err ( "Failed to load config" ) ,
205+ }
206+ } else {
207+ Err ( "No API available?!" )
208+ }
209+ }
210+
211+ fn save ( & self ) -> Result < ( ) , & ' static str > {
212+ if let Some ( api) = unsafe { API } {
213+ let mut buffer = [ 0u8 ; 64 ] ;
214+ let slice =
215+ postcard:: to_slice ( self , & mut buffer) . map_err ( |_e| "Failed to parse config" ) ?;
216+ ( api. configuration_set ) ( bios:: ApiByteSlice :: new ( slice) ) ;
217+ Ok ( ( ) )
218+ } else {
219+ Err ( "No API available?!" )
222220 }
223221 }
224222
225223 /// Should this system use the VGA console?
226224 fn has_vga_console ( & self ) -> bool {
227- self . vga_console
225+ self . vga_console_on
228226 }
229227
230228 /// Should this system use the UART console?
231229 fn has_serial_console ( & self ) -> Option < ( u8 , bios:: serial:: Config ) > {
232- if self . serial_console {
230+ if self . serial_console_on {
233231 Some ( (
234232 0 ,
235233 bios:: serial:: Config {
236- data_rate_bps : 115200 ,
234+ data_rate_bps : self . serial_baud ,
237235 data_bits : bios:: serial:: DataBits :: Eight ,
238236 stop_bits : bios:: serial:: StopBits :: One ,
239237 parity : bios:: serial:: Parity :: None ,
@@ -246,6 +244,38 @@ impl Config {
246244 }
247245}
248246
247+ impl core:: default:: Default for Config {
248+ fn default ( ) -> Config {
249+ Config {
250+ vga_console_on : true ,
251+ serial_console_on : false ,
252+ serial_baud : 115200 ,
253+ }
254+ }
255+ }
256+
257+ // ===========================================================================
258+ // Private functions
259+ // ===========================================================================
260+
261+ /// Initialise our global variables - the BIOS will not have done this for us
262+ /// (as it doesn't know where they are).
263+ unsafe fn start_up_init ( ) {
264+ extern "C" {
265+
266+ // These symbols come from `link.x`
267+ static mut __sbss: u32 ;
268+ static mut __ebss: u32 ;
269+
270+ static mut __sdata: u32 ;
271+ static mut __edata: u32 ;
272+ static __sidata: u32 ;
273+ }
274+
275+ r0:: zero_bss ( & mut __sbss, & mut __ebss) ;
276+ r0:: init_data ( & mut __sdata, & mut __edata, & __sidata) ;
277+ }
278+
249279// ===========================================================================
250280// Public functions / impl for public types
251281// ===========================================================================
@@ -258,7 +288,7 @@ extern "C" fn main(api: &'static bios::Api) -> ! {
258288 API = Some ( api) ;
259289 }
260290
261- let config = Config :: new ( ) ;
291+ let config = Config :: load ( ) . unwrap_or_else ( |_| Config :: default ( ) ) ;
262292
263293 if config. has_vga_console ( ) {
264294 let mut addr: * mut u8 = core:: ptr:: null_mut ( ) ;
0 commit comments