Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setup console from Device Tree (3) #1433

Merged
merged 7 commits into from
Apr 28, 2017
Merged

Setup console from Device Tree (3) #1433

merged 7 commits into from
Apr 28, 2017

Conversation

jforissier
Copy link
Contributor

This is the third rework of my proof-of-concept code to use DT in OP-TEE to configure devices, namely: the console UART.

@jforissier
Copy link
Contributor Author

This PR can be logically split in 3 parts:

  • The first 4 commits deal with basic DT support for OP-TEE drivers,
  • The 5th and 6th commits add DT support for the PL011 serial driver,
  • The 7th commit reads the console configuration from DT (PL011 only)

@jforissier
Copy link
Contributor Author

Rebased and Travis errors (checkpatch) fixed. Any feedback?

* for which we have a compatible driver. If so, switch the console to
* this device.
*/
static void configure_console_from_dt(unsigned long phys_fdt)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could move out of generic_boot.c ? maybe core/kernel/console.c.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

core/kernel/dt.c Outdated
return (!strncmp(st, "ok", len));
}

int _fdt_get_status(const void *fdt, int offs, int *status)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could return void or status.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, will return status

core/kernel/dt.c Outdated
/* Both "ok" and "okay" are valid */
if (len > 2)
len = 2;
return (!strncmp(st, "ok", len));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to strictly test "ok" and "okay".
Monir: null string returning OK status could also be handle in this function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to strictly test "ok" and "okay".

Yep.

Monir: null string returning OK status could also be handle in this function.

That wouldn't help much -- would not work for secure-status which defaults to the same value as status when null (i.e., not always "okay").

return NULL;
}

#define __dt_driver
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If CFG_DT is not defined, i could be nice to not define neither __dt_driver to insure one cannot implement DT dependent resources without enabling CFG_DT=y.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK.

* means we don't want any console output
*/
IMSG("Switching off console");
register_serial_console(NULL);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mandates a secure-chosen stdout-path in the DT. I think it is too restrictive.
One could define a DT aware uart driver in OP-TEE and expect the DT parser to find the related node, and register the console upon value of the property "secure-status".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that if /secure-chosen does not exist in the DT, the function does nothing (see a few lines above).

Also, there could be several UART devices with secure-status = okay, which one would you use as the console? This is really the job of the /[secure-]chosen node: pass some configuration parameters from the firmware to the [secure] OS. In addition, there might be additional configuration parameter (baud rate, parity) which really belong in /[secure-]chosen/stdout-path. This is well documented already (https://www.kernel.org/doc/Documentation/devicetree/bindings/chosen.txt).

break;
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems quite generic to DT parsing in OP-TEE. Could it be moved to your new core/kernel/dt.c.
(It look a lot like the dt_find_driver() you implemented)

goto out;
}

IMSG("Switching console to device: %s", uart);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: I would move this trace either before the new device init (before console_flush()) or after the new device registering.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not after the new console has registered, because I want it to appear on the "old" console (assuming they're different) to help the user understand where the subsequent output will go.

About moving it before console_flush(): we don't know yet if the init of the new console is OK (and we don't want to print the message if it failed). Would you want a console_flush() after this DMSG()? Seems pretty useless.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wondering if old and new console are the same, won't it mess in some way if core it pushing traces after the device init but before its registration.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm no, I don't think so. register_serial_console() only sets a pointer.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

*/
void configure_console_from_dt(unsigned long phys_fdt)
{
const struct dt_driver *drv, *found = NULL;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: 1 line per variable.

core/kernel/dt.c Outdated
assert(cpu_mmu_enabled());

st = _fdt_get_status(fdt, offs);
if (st == -1 || st == DT_STATUS_DISABLED)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: We don't expect st == -1 when CFG_DT is enable.

Copy link
Contributor

@etienne-lms etienne-lms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look ok to me. Still few minor comment (there will always be).
Yet: Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>

It is mergeable, due to deps on node "/secure-chosen" ?.

goto out;
}

IMSG("Switching console to device: %s", uart);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

core/kernel/dt.c Outdated
st = fdt_node_check_compatible(fdt, offs,
dm->compatible);
if (!st)
return drv;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: could get rid of st

*/
#define DT_STATUS_DISABLED 0
#define DT_STATUS_OK_NSEC 1
#define DT_STATUS_OK_SEC 2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since DT_STATUS_OK_NSEC/SEC are bit fields, it would be more explicit with

#define DT_STATUS_OK_NSEC  BIT(0)
#define DT_STATUS_OK_NSEC  BIT(1)

@jforissier
Copy link
Contributor Author

Additional comments addressed, rebased on top of master. Will add the review tags later. Since I am introducing new framework code, I'd like Reviewed-bys or Acked-bys from @jenswi-linaro and/or @jbech-linaro especially.

@etienne-lms this can safely be merged, because the dependency on /secure-chosen is not a 'hard' one: the code will do nothing when the node is not present.

const void *driver;
};

#define __dt_driver __attribute__((__section__(".rodata.dtdrv")))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please base it on __section() instead


#define __dt_driver __attribute__((__section__(".rodata.dtdrv")))

extern struct dt_driver __rodata_dtdrv_start, __rodata_dtdrv_end;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it work to make them const?

core/kernel/dt.c Outdated

static bool is_okay(const char *st, int len)
{
return (!strncmp(st, "ok", len) || !strncmp(st, "okay", len));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Outer parenthesis not needed.

core/kernel/dt.c Outdated
else
mtype = MEM_AREA_IO_NSEC;

vbase = (vaddr_t)phys_to_virt(pbase, mtype);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about pbase + sz - 1?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you check that the base address is mapped, but not the entire space needed for the device.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yes, I assumed the memory would normally be mapped only through this function, which is obviously wrong. I'll fix.

@jenswi-linaro
Copy link
Contributor

Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>

Use the functions provided by libfdt instead of our own.

Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
When CFG_DT=y, a linker section is created (.rodata.dtdrv) to hold all
the DT-compatible drivers. The table can later be queried at runtime.
Some manipulation functions are exported in <kernel/dt.h>.

Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Maps a device into memory from its FDT node.

Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Add struct serial_driver which will be useful to UART drivers that
want to create devices from a DT node.

Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
…path

If CFG_DT=y, check the Device Tree's /secure-chosen node and look for
the stdout-path property. Adjust the console output accordingly.
The DT bindings for this property have been proposed on the LKML [1].

[1] https://www.spinics.net/lists/arm-kernel/msg566034.html

Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
Tested-by: Jerome Forissier <jerome.forissier@linaro.org> (QEMU)
Reviewed-by: Etienne Carriere <etienne.carriere@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants