diff mbox

[4/4] ARM: tegra210: gpu: configure WPR region

Message ID 1445230624-30314-5-git-send-email-acourbot@nvidia.com
State Deferred
Headers show

Commit Message

Alexandre Courbot Oct. 19, 2015, 4:57 a.m. UTC
T210's GPU secure firmware loading requires a write-protected region
to be set up.

This patch reserves the upper 256KB of RAM as the WPR region and locks
it so the kernel can initiate secure firmware loading.

Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
 arch/arm/include/asm/arch-tegra210/mc.h | 12 +++++++++
 arch/arm/mach-tegra/board.c             |  4 +++
 arch/arm/mach-tegra/gpu.c               | 47 ++++++++++++++++++++++++++++++++-
 3 files changed, 62 insertions(+), 1 deletion(-)

Comments

Stephen Warren Oct. 28, 2015, 5:59 p.m. UTC | #1
On 10/18/2015 10:57 PM, Alexandre Courbot wrote:
> T210's GPU secure firmware loading requires a write-protected region
> to be set up.
>
> This patch reserves the upper 256KB of RAM as the WPR region and locks
> it so the kernel can initiate secure firmware loading.

On T210, it's the responsibility of nvtboot (which runs before U-Boot) 
to set up any and all carve-outs. This code should not be necessary, and 
indeed I expect the registers it touches can't actually be programmed 
from U-Boot, which runs in non-secure mode after WPR is already locked.
--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Alexandre Courbot Oct. 28, 2015, 11:55 p.m. UTC | #2
On 10/29/2015 02:59 AM, Stephen Warren wrote:
> On 10/18/2015 10:57 PM, Alexandre Courbot wrote:
>> T210's GPU secure firmware loading requires a write-protected region
>> to be set up.
>>
>> This patch reserves the upper 256KB of RAM as the WPR region and locks
>> it so the kernel can initiate secure firmware loading.
>
> On T210, it's the responsibility of nvtboot (which runs before U-Boot)
> to set up any and all carve-outs. This code should not be necessary, and
> indeed I expect the registers it touches can't actually be programmed
> from U-Boot, which runs in non-secure mode after WPR is already locked.

Ok, I was running from Thierry's miniloader which did not program or 
lock these registers.

The question then is: do we have an official nvtboot binary available 
for upstream support? AFAICT Thierry's miniloader solution is the only 
solution available to the public, and without this setup one cannot use 
the GPU on T210.
--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Stephen Warren Oct. 29, 2015, 3:47 a.m. UTC | #3
On 10/28/2015 05:55 PM, Alexandre Courbot wrote:
> On 10/29/2015 02:59 AM, Stephen Warren wrote:
>> On 10/18/2015 10:57 PM, Alexandre Courbot wrote:
>>> T210's GPU secure firmware loading requires a write-protected region
>>> to be set up.
>>>
>>> This patch reserves the upper 256KB of RAM as the WPR region and locks
>>> it so the kernel can initiate secure firmware loading.
>>
>> On T210, it's the responsibility of nvtboot (which runs before U-Boot)
>> to set up any and all carve-outs. This code should not be necessary, and
>> indeed I expect the registers it touches can't actually be programmed
>> from U-Boot, which runs in non-secure mode after WPR is already locked.
> 
> Ok, I was running from Thierry's miniloader which did not program or
> lock these registers.
> 
> The question then is: do we have an official nvtboot binary available
> for upstream support? AFAICT Thierry's miniloader solution is the only
> solution available to the public, and without this setup one cannot use
> the GPU on T210.

Once L4T for T210 has been released, it'll contain a full set of nvtboot
binaries and flashing support. You an easily acquire this internally
already; send me an email if you need a link. I'd expect a public SW
release by the time any T210 boards capable of running upstream are
available.
--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Thierry Reding Nov. 9, 2015, 2:36 p.m. UTC | #4
On Wed, Oct 28, 2015 at 11:59:04AM -0600, Stephen Warren wrote:
> On 10/18/2015 10:57 PM, Alexandre Courbot wrote:
> >T210's GPU secure firmware loading requires a write-protected region
> >to be set up.
> >
> >This patch reserves the upper 256KB of RAM as the WPR region and locks
> >it so the kernel can initiate secure firmware loading.
> 
> On T210, it's the responsibility of nvtboot (which runs before U-Boot) to
> set up any and all carve-outs. This code should not be necessary, and indeed
> I expect the registers it touches can't actually be programmed from U-Boot,
> which runs in non-secure mode after WPR is already locked.

Can we document this assumption somewhere? It's entirely possible that
someone might want to run U-Boot without nvtboot, in which case nvtboot
would still need to be responsible for setting this up. Or if it isn't
we could still point at some location where the interactions between a
first stage bootloader and U-Boot are documented.

Do we have a document of this kind already?

Thierry
Stephen Warren Nov. 9, 2015, 3:19 p.m. UTC | #5
On 11/09/2015 07:36 AM, Thierry Reding wrote:
> On Wed, Oct 28, 2015 at 11:59:04AM -0600, Stephen Warren wrote:
>> On 10/18/2015 10:57 PM, Alexandre Courbot wrote:
>>> T210's GPU secure firmware loading requires a write-protected region
>>> to be set up.
>>>
>>> This patch reserves the upper 256KB of RAM as the WPR region and locks
>>> it so the kernel can initiate secure firmware loading.
>>
>> On T210, it's the responsibility of nvtboot (which runs before U-Boot) to
>> set up any and all carve-outs. This code should not be necessary, and indeed
>> I expect the registers it touches can't actually be programmed from U-Boot,
>> which runs in non-secure mode after WPR is already locked.
>
> Can we document this assumption somewhere? It's entirely possible that
> someone might want to run U-Boot without nvtboot

That's not currently a supported use-case.

> , in which case nvtboot
> would still need to be responsible for setting this up.

I assume s/nvtboot/whatever other bootloader is in use/?

> Or if it isn't
> we could still point at some location where the interactions between a
> first stage bootloader and U-Boot are documented.
>
> Do we have a document of this kind already?

The L4T U-Boot source code:-)
--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Thierry Reding Nov. 9, 2015, 3:48 p.m. UTC | #6
On Mon, Nov 09, 2015 at 08:19:48AM -0700, Stephen Warren wrote:
> On 11/09/2015 07:36 AM, Thierry Reding wrote:
> >On Wed, Oct 28, 2015 at 11:59:04AM -0600, Stephen Warren wrote:
> >>On 10/18/2015 10:57 PM, Alexandre Courbot wrote:
> >>>T210's GPU secure firmware loading requires a write-protected region
> >>>to be set up.
> >>>
> >>>This patch reserves the upper 256KB of RAM as the WPR region and locks
> >>>it so the kernel can initiate secure firmware loading.
> >>
> >>On T210, it's the responsibility of nvtboot (which runs before U-Boot) to
> >>set up any and all carve-outs. This code should not be necessary, and indeed
> >>I expect the registers it touches can't actually be programmed from U-Boot,
> >>which runs in non-secure mode after WPR is already locked.
> >
> >Can we document this assumption somewhere? It's entirely possible that
> >someone might want to run U-Boot without nvtboot
> 
> That's not currently a supported use-case.

Isn't the whole point of open-source for people to be able to do all the
things that aren't supported?

> >, in which case nvtboot
> >would still need to be responsible for setting this up.
> 
> I assume s/nvtboot/whatever other bootloader is in use/?

Right, I was going to write U-Boot here, but that's obviously only true
if U-Boot is still running in secure mode. Otherwise, yes, it'd be what-
ever is the other bootloader being used.

> >Or if it isn't
> >we could still point at some location where the interactions between a
> >first stage bootloader and U-Boot are documented.
> >
> >Do we have a document of this kind already?
> 
> The L4T U-Boot source code:-)

There's a bunch of things that even the L4T U-Boot doesn't document. The
fact that it doesn't initialize the SMMU or WPR doesn't indicate that it
is something that a first stage bootloader needs to do.

Thierry
Stephen Warren Nov. 9, 2015, 4:18 p.m. UTC | #7
On 11/09/2015 08:48 AM, Thierry Reding wrote:
> On Mon, Nov 09, 2015 at 08:19:48AM -0700, Stephen Warren wrote:
>> On 11/09/2015 07:36 AM, Thierry Reding wrote:
>>> On Wed, Oct 28, 2015 at 11:59:04AM -0600, Stephen Warren wrote:
>>>> On 10/18/2015 10:57 PM, Alexandre Courbot wrote:
>>>>> T210's GPU secure firmware loading requires a write-protected region
>>>>> to be set up.
>>>>>
>>>>> This patch reserves the upper 256KB of RAM as the WPR region and locks
>>>>> it so the kernel can initiate secure firmware loading.
>>>>
>>>> On T210, it's the responsibility of nvtboot (which runs before U-Boot) to
>>>> set up any and all carve-outs. This code should not be necessary, and indeed
>>>> I expect the registers it touches can't actually be programmed from U-Boot,
>>>> which runs in non-secure mode after WPR is already locked.
>>>
>>> Can we document this assumption somewhere? It's entirely possible that
>>> someone might want to run U-Boot without nvtboot
>>
>> That's not currently a supported use-case.
>
> Isn't the whole point of open-source for people to be able to do all the
> things that aren't supported?

Sure, but the default case that we support should "just work", and be 
represented by the code we ship, and be supported by us. Any non-default 
case is going to require some research or additional coding/fixing/... 
effort, and we haven't necessarily published the information require to 
make those cases work.

>>> , in which case nvtboot
>>> would still need to be responsible for setting this up.
>>
>> I assume s/nvtboot/whatever other bootloader is in use/?
>
> Right, I was going to write U-Boot here, but that's obviously only true
> if U-Boot is still running in secure mode. Otherwise, yes, it'd be what-
> ever is the other bootloader being used.
>
>>> Or if it isn't
>>> we could still point at some location where the interactions between a
>>> first stage bootloader and U-Boot are documented.
>>>
>>> Do we have a document of this kind already?
>>
>> The L4T U-Boot source code:-)
>
> There's a bunch of things that even the L4T U-Boot doesn't document. The
> fact that it doesn't initialize the SMMU or WPR doesn't indicate that it
> is something that a first stage bootloader needs to do.

I meant this more along the lines of "if there's no code to do something 
in L4T U-Boot, upstream U-Boot wouldn't need that code either". That 
should be true at least w.r.t. nvtboot integration; certainly there are 
features that only exist in upstream U-Boot and haven't been back-ported 
downstream. I wasn't really implying that there's actual documentation 
(comments) in the L4T U-Boot source code.
--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/arm/include/asm/arch-tegra210/mc.h b/arch/arm/include/asm/arch-tegra210/mc.h
index 77e9aa51f60f..e6d1758d372f 100644
--- a/arch/arm/include/asm/arch-tegra210/mc.h
+++ b/arch/arm/include/asm/arch-tegra210/mc.h
@@ -62,6 +62,16 @@  struct mc_ctlr {
 	u32 mc_video_protect_bom;		/* offset 0x648 */
 	u32 mc_video_protect_size_mb;		/* offset 0x64c */
 	u32 mc_video_protect_reg_ctrl;		/* offset 0x650 */
+	u32 reserved11[385];			/* offset 0x654 - 0xc54 */
+	u32 mc_security_carveout2_cfg0;		/* offset 0xc58 */
+	u32 mc_security_carveout2_bom;		/* offset 0xc5c */
+	u32 mc_security_carveout2_bom_hi;	/* offset 0xc60 */
+	u32 mc_security_carveout2_size_128k;	/* offset 0xc64 */
+	u32 reserved12[16];			/* offset 0xc68 - 0xca4 */
+	u32 mc_security_carveout3_cfg0;		/* offset 0xca8 */
+	u32 mc_security_carveout3_bom;		/* offset 0xcac */
+	u32 mc_security_carveout3_bom_hi;	/* offset 0xcb0 */
+	u32 mc_security_carveout3_size_128k;	/* offset 0xcb4 */
 };
 
 #define TEGRA_MC_SMMU_CONFIG_ENABLE (1 << 0)
@@ -69,4 +79,6 @@  struct mc_ctlr {
 #define TEGRA_MC_VIDEO_PROTECT_REG_WRITE_ACCESS_ENABLED		(0 << 0)
 #define TEGRA_MC_VIDEO_PROTECT_REG_WRITE_ACCESS_DISABLED	(1 << 0)
 
+#define TEGRA_MC_SECURITY_CARVEOUT_CFG_LOCKED			(1 << 1)
+
 #endif	/* _TEGRA210_MC_H_ */
diff --git a/arch/arm/mach-tegra/board.c b/arch/arm/mach-tegra/board.c
index b00e4b5c1e25..0bff063b00f4 100644
--- a/arch/arm/mach-tegra/board.c
+++ b/arch/arm/mach-tegra/board.c
@@ -111,6 +111,10 @@  static phys_size_t query_sdram_size(void)
 	if (size_bytes == SZ_2G)
 		size_bytes -= SZ_1M;
 #endif
+#if defined(CONFIG_TEGRA210)
+	/* Reserve GPU WPR area, 2 * 128KB */
+	size_bytes = round_down(size_bytes - (SZ_128K * 2), SZ_128K);
+#endif
 
 	return size_bytes;
 }
diff --git a/arch/arm/mach-tegra/gpu.c b/arch/arm/mach-tegra/gpu.c
index c7d705d8efe9..61d734fd5767 100644
--- a/arch/arm/mach-tegra/gpu.c
+++ b/arch/arm/mach-tegra/gpu.c
@@ -23,9 +23,11 @@ 
 
 #include <fdt_support.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 static bool _configured;
 
-void tegra_gpu_config(void)
+static void config_vpr(void)
 {
 	struct mc_ctlr *mc = (struct mc_ctlr *)NV_PA_MC_BASE;
 
@@ -37,6 +39,49 @@  void tegra_gpu_config(void)
 	readl(&mc->mc_video_protect_reg_ctrl);
 
 	debug("configured VPR\n");
+}
+
+#if defined(CONFIG_TEGRA210)
+static void config_wpr(void)
+{
+	struct mc_ctlr *mc = (struct mc_ctlr *)NV_PA_MC_BASE;
+	u64 wpr_start = NV_PA_SDRAM_BASE + gd->ram_size;
+	u32 reg;
+
+	/*
+	 * Carveout2 uses the upper 256KB of upper memory that we reserved as
+	 * WPR region for secure firmware loading
+	 */
+	writel(lower_32_bits(wpr_start), &mc->mc_security_carveout2_bom);
+	writel(upper_32_bits(wpr_start), &mc->mc_security_carveout2_bom_hi);
+	writel(0x2, &mc->mc_security_carveout2_size_128k);
+	reg = readl(&mc->mc_security_carveout2_cfg0);
+	reg |= TEGRA_MC_SECURITY_CARVEOUT_CFG_LOCKED;
+	writel(reg, &mc->mc_security_carveout2_cfg0);
+
+	/* Carveout3 is left empty */
+	writel(0x0, &mc->mc_security_carveout3_bom);
+	writel(0x0, &mc->mc_security_carveout3_bom_hi);
+	writel(0x0, &mc->mc_security_carveout3_size_128k);
+	reg = readl(&mc->mc_security_carveout3_cfg0);
+	reg |= TEGRA_MC_SECURITY_CARVEOUT_CFG_LOCKED;
+	writel(reg, &mc->mc_security_carveout3_cfg0);
+
+	/* read back to ensure the write went through */
+	readl(&mc->mc_security_carveout3_cfg0);
+
+	debug("configured WPR\n");
+}
+#else
+static inline void config_wpr(void)
+{
+}
+#endif
+
+void tegra_gpu_config(void)
+{
+	config_vpr();
+	config_wpr();
 
 	_configured = true;
 }