<div dir="auto"><div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, 30 Dec, 2019, 2:07 AM Christian Mauderer, <<a href="mailto:list@c-mauderer.de">list@c-mauderer.de</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I assume you want suggestions regarding this code rather than the<br>
original patch?<br>
<br>
One suggestion: If you post code please try to use a mail program that<br>
keeps the indentation. It's hard to read in this form. But that's most<br>
likely not the suggestion you searched for ;-)<br>
<br>
On 29/12/2019 19:48, Niteesh wrote:<br>
> I am not happy with my code at all, I can please provide some suggestions.<br>
> <br>
> On Mon, Dec 30, 2019 at 12:17 AM Niteesh <<a href="mailto:gsnb.gn@gmail.com" target="_blank" rel="noreferrer">gsnb.gn@gmail.com</a><br>
> <mailto:<a href="mailto:gsnb.gn@gmail.com" target="_blank" rel="noreferrer">gsnb.gn@gmail.com</a>>> wrote:<br>
> <br>
> arm_pl011_context pl011_context;<br>
> rpi_fb_context fb_context;<br>
<br>
Is it sure that we only ever have one UART of each type? Otherwise some<br>
dynamic handling (allocating the memory for the context) might would be<br>
necessary. I think the chip has only these two modules? In that case<br>
this is OK for now.</blockquote></div></div><div dir="auto">I just checked the uarts for rpi4, it has 6uarts not sure which model they are though.</div><div dir="auto">My idea is to call all the uart register functions, register_pl011, register_aux or register_xxx inside uart_probe which will see if they can handle that particular node. If not they just return. The FB is registered seperately in the console_initialise. Are you okay with or would like to change something?</div><div dir="auto"></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
> char uart_instance[20];<br>
> <br>
<br>
A global just to pass a name around? Would it be possible to search for<br>
a more elegant solution?<br></blockquote></div></div><div dir="auto">I first was setting the name for the uarts from the fdt property itself. In fdt, the pl011 is uart0 and aux is uart1. So the correct path name is set from the fdt property itself. For eg: if the current node is uart0 it will be /dev/ttyS0 and ttyS1 if uart1. Is this approach fine?</div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
> <br>
> static void output_char_serial(char c)<br>
> {<br>
> arm_pl011_write_polled(&pl011_context.base, c);<br>
> }<br>
> <br>
> void output_char_fb(char c)<br>
> {<br>
> fbcons_write_polled(&fb_context.base, c);<br>
> }<br>
> <br>
> <br>
> static void *get_reg_of_node(const void *fdt, int node)<br>
> {<br>
> int len;<br>
> const uint32_t *val;<br>
> <br>
> val = fdt_getprop(fdt, node, "reg", &len);<br>
> if (val == NULL || len < 4) {<br>
> return NULL;<br>
> }<br>
> <br>
> return (void *) fdt32_to_cpu(val[0]);<br>
> }<br>
> <br>
> static void arm_pl011_init_ctx(<br>
> const void *fdt,<br>
> const char *serial<br>
> )<br>
> {<br>
> arm_pl011_context *ctx = &pl011_context;<br>
> int node;<br>
> <br>
> if (strcmp(serial, "uart0") == 0) {<br>
> <br>
> rtems_termios_device_context_initialize(&ctx->base, "UART");<br>
> node = fdt_path_offset(fdt, serial);<br>
> ctx->regs = get_reg_of_node(fdt, node);<br>
> }<br>
> }<br>
> <br>
> static void console_select( const char *console )<br>
> {<br>
> const char *opt;<br>
> <br>
> opt = rpi_cmdline_get_arg("--console=");<br>
> <br>
> if ( opt ) {<br>
> if ( strncmp( opt, "fbcons", sizeof( "fbcons" ) - 1 ) == 0 ) {<br>
> if ( rpi_video_is_initialized() > 0 ) {<br>
> strcpy(uart_instance, "/dev/fbcons");<br>
> BSP_output_char = output_char_fb;<br>
> }<br>
> }else{<br>
> <br>
> if ( console == NULL ){<br>
> bsp_fatal( BSP_FATAL_CONSOLE_NO_DEV );<br>
> }<br>
> BSP_output_char = output_char_serial;<br>
> strcpy(uart_instance, "/dev/ttyS0");<br>
> }<br>
> }<br>
> }<br>
> <br>
> static void uart_probe(void)<br>
> {<br>
> const void *fdt;<br>
> const char *console;<br>
> int node;<br>
> <br>
> fdt = bsp_fdt_get();<br>
> node = fdt_path_offset(fdt, "/chosen");<br>
> <br>
> console = fdt_getprop(fdt, node, "stdout-path", NULL);<br>
> <br>
> node = fdt_path_offset(fdt, "/aliases");<br>
> <br>
> int offset = fdt_first_property_offset(fdt, node);<br>
> <br>
> while (offset >= 0) {<br>
> const struct fdt_property *prop;<br>
> prop = fdt_get_property_by_offset(fdt, offset, NULL);<br>
> if (prop != NULL) {<br>
> const char *name;<br>
> <br>
> name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));<br>
> if(strstr(name, "serial") != NULL) {<br>
> const char *serial;<br>
> serial = prop->data;<br>
> <br>
> arm_pl011_init_ctx(fdt, serial);<br>
> }<br>
> }<br>
> <br>
> offset = fdt_next_property_offset(fdt, offset);<br>
> }<br>
> console_select(console);<br>
> }<br>
<br>
I assume that you copied most of that from the imx uart? For the<br>
raspberry I would suggest to search for a node that is compatible with<br>
the device. Use fdt_node_offset_by_compatible(...) for that. I'm not<br>
sure whether there is the same path structure in the raspberry fdt like<br>
in the imx fdt (with a "chosen" path and a "stdout-path").<br></blockquote></div></div><div dir="auto">I did checkout the dts file from FreeBSD, it does use the same path structure as imx.</div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I'm not sure whether fdt_node_offset_by_compatible(...) delivers only<br>
eneabled ones so you may have to loop over all compatible nodes and<br>
search for an enabled one.<br></blockquote></div></div><div dir="auto">Can we please explain what does fdt_node_offset_by_compatible do??</div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
> <br>
> <br>
> static void output_char(char c)<br>
> {<br>
> uart_probe();<br>
> (*BSP_output_char)(c);<br>
> }<br>
> <br>
<br>
Seems like a hack in the imx BSP. I'm not sure whether it is a good<br>
idea. Maybe it is possible to construct a case where uart_probe is<br>
called twice.<br>
<br>
> rtems_status_code console_initialize(<br>
> rtems_device_major_number major,<br>
> rtems_device_minor_number minor,<br>
> void *arg<br>
> )<br>
> {<br>
> <br>
> rtems_termios_initialize();<br>
> rtems_termios_device_install(<br>
> "/dev/ttyS0",<br>
> &arm_pl011_fns,<br>
> NULL,<br>
> &pl011_context.base<br>
> );<br>
> rtems_termios_device_install(<br>
> "/dev/fbcons",<br>
> &fbcons_fns,<br>
> NULL,<br>
> &fb_context.base);<br>
> <br>
> link(uart_instance, CONSOLE_DEVICE_NAME);<br>
> <br>
> return RTEMS_SUCCESSFUL;<br>
> }<br>
> <br>
> BSP_output_char_function_type BSP_output_char = output_char;<br>
> <br>
> BSP_polling_getchar_function_type BSP_poll_char = NULL;<br>
> <br>
> RTEMS_SYSINIT_ITEM(<br>
> uart_probe,<br>
> RTEMS_SYSINIT_BSP_START,<br>
> RTEMS_SYSINIT_ORDER_LAST<br>
> );<br>
<br>
Till now the console_initialize was able to do the frame buffer<br>
initialization on the raspberry, correct? So maybe it would be possible<br>
to just do the stuff from uart_probe in the console_initialize?<br></blockquote></div></div><div dir="auto">When is console_initialize called. I first had the uart probe in console_initialize. But the console_initialize was never called. So I moved it to output char.</div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
</blockquote></div></div></div>