44 * Copyright (c) 2019 Western Digital Corporation or its affiliates.
55 */
66
7+ #include <libfdt.h>
8+
79#include <sbi/riscv_asm.h>
810#include <sbi/riscv_encoding.h>
11+ #include <sbi/sbi_console.h>
912#include <sbi/sbi_const.h>
13+ #include <sbi/sbi_error.h>
1014#include <sbi/sbi_platform.h>
15+ #include <sbi/sbi_timer.h>
1116
17+ #include <sbi_utils/fdt/fdt_fixup.h>
18+ #include <sbi_utils/fdt/fdt_helper.h>
1219#include <sbi_utils/serial/xlnx_uartlite.h>
1320#include <sbi_utils/timer/aclint_mtimer.h>
1421
@@ -41,6 +48,97 @@ static int mlogv32_early_init(bool cold_boot)
4148 return xlnx_uartlite_init (MLOGV32_UART0_ADDR );
4249}
4350
51+ static char mlogv32_bootargs [256 ];
52+
53+ static void mlogv32_do_fixup (struct fdt_general_fixup * f , void * fdt ) {
54+ if (!mlogv32_bootargs [0 ])
55+ return ;
56+
57+ int chosen_offset = fdt_path_offset (fdt , "/chosen" );
58+ if (chosen_offset < 0 )
59+ return ;
60+
61+ int err = fdt_setprop_string (fdt , chosen_offset , "bootargs" , mlogv32_bootargs );
62+ if (err )
63+ sbi_printf ("Failed to set bootargs: %s" , fdt_strerror (err ));
64+ }
65+
66+ static struct fdt_general_fixup mlogv32_fixup = {
67+ .name = "mlogv32-fixup" ,
68+ .do_fixup = mlogv32_do_fixup ,
69+ };
70+
71+ static bool mlogv32_wait_for_input (void * arg ) {
72+ return sbi_getc () >= 0 ;
73+ }
74+
75+ static bool mlogv32_prompt_interrupt_boot (void ) {
76+ bool retval = false;
77+ sbi_printf ("Press any key to interrupt boot" );
78+ for (int i = 0 ; i < 3 ; i ++ ) {
79+ sbi_printf ("." );
80+ if (sbi_timer_waitms_until (mlogv32_wait_for_input , NULL , 1000 )) {
81+ retval = true;
82+ break ;
83+ }
84+ }
85+ sbi_printf ("\n" );
86+ return retval ;
87+ }
88+
89+ static const char * mlogv32_get_fdt_bootargs (void * fdt ) {
90+ int chosen_offset = fdt_path_offset (fdt , "/chosen" );
91+ if (chosen_offset < 0 )
92+ return NULL ;
93+
94+ return fdt_getprop (fdt , chosen_offset , "bootargs" , NULL );
95+ }
96+
97+ static void mlogv32_prompt_get_bootargs (void * fdt ) {
98+ // drain input buffer
99+ while (mlogv32_wait_for_input (NULL )) {}
100+
101+ const char * current_bootargs = mlogv32_get_fdt_bootargs (fdt );
102+ if (current_bootargs )
103+ sbi_printf ("Bootargs: %s\n" , current_bootargs );
104+
105+ if (!mlogv32_prompt_interrupt_boot ())
106+ return ;
107+
108+ while (mlogv32_wait_for_input (NULL )) {}
109+
110+ sbi_printf ("Enter new bootargs: " );
111+
112+ char * retval = mlogv32_bootargs ;
113+ int maxwidth = sizeof (mlogv32_bootargs );
114+ while (maxwidth > 1 ) {
115+ int ch = sbi_getc ();
116+ if (ch <= 0 )
117+ continue ;
118+
119+ // backspace
120+ if (ch == 127 ) {
121+ if (retval > mlogv32_bootargs ) {
122+ sbi_puts ("\b \b" );
123+ retval -- ;
124+ maxwidth ++ ;
125+ }
126+ continue ;
127+ }
128+
129+ sbi_putc (ch );
130+
131+ if (ch == '\r' || ch == '\n' ) {
132+ break ;
133+ }
134+
135+ * retval = (char )ch ;
136+ retval ++ ;
137+ maxwidth -- ;
138+ }
139+ * retval = '\0' ;
140+ }
141+
44142/*
45143 * Platform final initialization.
46144 */
@@ -49,6 +147,20 @@ static int mlogv32_final_init(bool cold_boot)
49147 // delegate UART interrupts to S-mode
50148 csr_set (CSR_MIDELEG , MIP_MEIP );
51149
150+ if (!cold_boot )
151+ return 0 ;
152+
153+ void * fdt = fdt_get_address_rw ();
154+
155+ mlogv32_prompt_get_bootargs (fdt );
156+ sbi_printf ("\n\n" );
157+
158+ int rc = fdt_register_general_fixup (& mlogv32_fixup );
159+ if (rc && rc != SBI_EALREADY )
160+ return rc ;
161+
162+ fdt_fixups (fdt );
163+
52164 return 0 ;
53165}
54166
@@ -69,6 +181,7 @@ const struct sbi_platform_operations platform_ops = {
69181 .final_init = mlogv32_final_init ,
70182 .timer_init = mlogv32_timer_init
71183};
184+
72185const struct sbi_platform platform = {
73186 .opensbi_version = OPENSBI_VERSION ,
74187 .platform_version = SBI_PLATFORM_VERSION (0x0 , 0x00 ),
0 commit comments