diff mbox series

[v4,2/7] MIPS: Loongson64: Distinguish firmware dependencies DTB/LEFI

Message ID 20210310075639.20372-3-zhangqing@loongson.cn (mailing list archive)
State Superseded
Headers show
Series Add basic support for Loongson-2K1000 | expand

Commit Message

Qing Zhang March 10, 2021, 7:56 a.m. UTC
Add DTB boot support, only support Loongson-2K1000 processor
for now, determine whether to use the built-in DTB or the DTB
from the firmware by checking the range of CKSEG0 and XKPHYS.
loongson_fw_interface will be used in the future.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Qing Zhang <zhangqing@loongson.cn>
Tested-by: Ming Wang <wangming01@loongson.cn>
---

v3-v4: Standard submission of information
       Fix error handling 

 .../include/asm/mach-loongson64/boot_param.h     |  6 ++++++
 arch/mips/include/asm/mach-loongson64/loongson.h |  3 ++-
 arch/mips/loongson64/env.c                       | 13 ++++++++++++-
 arch/mips/loongson64/init.c                      | 16 ++++++++++++++--
 4 files changed, 34 insertions(+), 4 deletions(-)

Comments

Oleksij Rempel March 10, 2021, 10:57 a.m. UTC | #1
Hi,

Am 10.03.21 um 08:56 schrieb Qing Zhang:
> Add DTB boot support, only support Loongson-2K1000 processor
> for now, determine whether to use the built-in DTB or the DTB
> from the firmware by checking the range of CKSEG0 and XKPHYS.
> loongson_fw_interface will be used in the future.
>
> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> Signed-off-by: Qing Zhang <zhangqing@loongson.cn>
> Tested-by: Ming Wang <wangming01@loongson.cn>
> ---
>
> v3-v4: Standard submission of information
>        Fix error handling
>
>  .../include/asm/mach-loongson64/boot_param.h     |  6 ++++++
>  arch/mips/include/asm/mach-loongson64/loongson.h |  3 ++-
>  arch/mips/loongson64/env.c                       | 13 ++++++++++++-
>  arch/mips/loongson64/init.c                      | 16 ++++++++++++++--
>  4 files changed, 34 insertions(+), 4 deletions(-)
>
> diff --git a/arch/mips/include/asm/mach-loongson64/boot_param.h b/arch/mips/include/asm/mach-loongson64/boot_param.h
> index 4592841b6b0c..43737401dc06 100644
> --- a/arch/mips/include/asm/mach-loongson64/boot_param.h
> +++ b/arch/mips/include/asm/mach-loongson64/boot_param.h
> @@ -198,7 +198,13 @@ enum loongson_bridge_type {
>  	VIRTUAL = 3
>  };
>
> +enum loongson_fw_interface {
> +	LOONGSON_LEFI,
> +	LOONGSON_DTB,
> +};
> +
>  struct loongson_system_configuration {
> +	enum loongson_fw_interface fw_interface;
>  	u32 nr_cpus;
>  	u32 nr_nodes;
>  	int cores_per_node;
> diff --git a/arch/mips/include/asm/mach-loongson64/loongson.h b/arch/mips/include/asm/mach-loongson64/loongson.h
> index ac1c20e172a2..3f885fa26ba6 100644
> --- a/arch/mips/include/asm/mach-loongson64/loongson.h
> +++ b/arch/mips/include/asm/mach-loongson64/loongson.h
> @@ -23,7 +23,8 @@ extern u32 memsize, highmemsize;
>  extern const struct plat_smp_ops loongson3_smp_ops;
>
>  /* loongson-specific command line, env and memory initialization */
> -extern void __init prom_init_env(void);
> +extern void __init prom_dtb_init_env(void);
> +extern void __init prom_lefi_init_env(void);
>  extern void __init szmem(unsigned int node);
>  extern void *loongson_fdt_blob;
>
> diff --git a/arch/mips/loongson64/env.c b/arch/mips/loongson64/env.c
> index 51a5d050a94c..e7d3a06175e3 100644
> --- a/arch/mips/loongson64/env.c
> +++ b/arch/mips/loongson64/env.c
> @@ -43,7 +43,18 @@ const char *get_system_type(void)
>  	return "Generic Loongson64 System";
>  }
>
> -void __init prom_init_env(void)
> +
> +void __init prom_dtb_init_env(void)
> +{
> +	if ((fw_arg2 < CKSEG0 || fw_arg2 > CKSEG1)
> +		&& (fw_arg2 < XKPHYS || fw_arg2 > XKSEG))
> +
> +		loongson_fdt_blob = __dtb_loongson64_2core_2k1000_begin;
> +	else
> +		loongson_fdt_blob = (void *)fw_arg2;
> +}
> +
> +void __init prom_lefi_init_env(void)
>  {
>  	struct boot_params *boot_p;
>  	struct loongson_params *loongson_p;
> diff --git a/arch/mips/loongson64/init.c b/arch/mips/loongson64/init.c
> index cfa788bca871..ed280b73bf89 100644
> --- a/arch/mips/loongson64/init.c
> +++ b/arch/mips/loongson64/init.c
> @@ -52,6 +52,10 @@ void __init szmem(unsigned int node)
>  	static unsigned long num_physpages;
>  	u64 node_id, node_psize, start_pfn, end_pfn, mem_start, mem_size;
>
> +	/* Otherwise come from DTB */
> +	if (loongson_sysconf.fw_interface != LOONGSON_LEFI)
> +		return;
> +
>  	/* Parse memory information and activate */
>  	for (i = 0; i < loongson_memmap->nr_map; i++) {
>  		node_id = loongson_memmap->map[i].node_id;
> @@ -94,12 +98,20 @@ static void __init prom_init_memory(void)
>  void __init prom_init(void)
>  {
>  	fw_init_cmdline();
> -	prom_init_env();
> +
> +	if (fw_arg2 == 0 || (fdt_magic(fw_arg2) == FDT_MAGIC)) {
> +		loongson_sysconf.fw_interface = LOONGSON_DTB;
> +		prom_dtb_init_env();
> +	} else {
> +		loongson_sysconf.fw_interface = LOONGSON_LEFI;
> +		prom_lefi_init_env();
> +	}

Is it possible to make it compatible with MIPS UHI boot protocol? So boot loaders will be able to
handle Loongson kernel images as any other MIPS kernel images?

This protocol is described here on page 15, "3. Boot protocols"
https://docplayer.net/62444141-Unified-hosting-interface-md01069-reference-manual.html

According to this protocol, you should have:
fw_arg0 = -2
fw_arg1 = Virtual (kseg0) address of Device Tree Blob

This would made LS a first grade resident for many boot loaders and save a lot of needles headaches.

--
Regards,
Oleksij
Jiaxun Yang March 10, 2021, 12:12 p.m. UTC | #2
On Wed, Mar 10, 2021, at 6:57 PM, Oleksij Rempel wrote:
> Hi,
> 
> Am 10.03.21 um 08:56 schrieb Qing Zhang:
> > Add DTB boot support, only support Loongson-2K1000 processor
> > for now, determine whether to use the built-in DTB or the DTB
> > from the firmware by checking the range of CKSEG0 and XKPHYS.
> > loongson_fw_interface will be used in the future.
> >
> > Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> > Signed-off-by: Qing Zhang <zhangqing@loongson.cn>
> > Tested-by: Ming Wang <wangming01@loongson.cn>
> > ---
> >
> > v3-v4: Standard submission of information
> >        Fix error handling
> >
> >  .../include/asm/mach-loongson64/boot_param.h     |  6 ++++++
> >  arch/mips/include/asm/mach-loongson64/loongson.h |  3 ++-
> >  arch/mips/loongson64/env.c                       | 13 ++++++++++++-
> >  arch/mips/loongson64/init.c                      | 16 ++++++++++++++--
> >  4 files changed, 34 insertions(+), 4 deletions(-)
> >
> > diff --git a/arch/mips/include/asm/mach-loongson64/boot_param.h b/arch/mips/include/asm/mach-loongson64/boot_param.h
> > index 4592841b6b0c..43737401dc06 100644
> > --- a/arch/mips/include/asm/mach-loongson64/boot_param.h
> > +++ b/arch/mips/include/asm/mach-loongson64/boot_param.h
> > @@ -198,7 +198,13 @@ enum loongson_bridge_type {
> >  	VIRTUAL = 3
> >  };
> >
> > +enum loongson_fw_interface {
> > +	LOONGSON_LEFI,
> > +	LOONGSON_DTB,
> > +};
> > +
> >  struct loongson_system_configuration {
> > +	enum loongson_fw_interface fw_interface;
> >  	u32 nr_cpus;
> >  	u32 nr_nodes;
> >  	int cores_per_node;
> > diff --git a/arch/mips/include/asm/mach-loongson64/loongson.h b/arch/mips/include/asm/mach-loongson64/loongson.h
> > index ac1c20e172a2..3f885fa26ba6 100644
> > --- a/arch/mips/include/asm/mach-loongson64/loongson.h
> > +++ b/arch/mips/include/asm/mach-loongson64/loongson.h
> > @@ -23,7 +23,8 @@ extern u32 memsize, highmemsize;
> >  extern const struct plat_smp_ops loongson3_smp_ops;
> >
> >  /* loongson-specific command line, env and memory initialization */
> > -extern void __init prom_init_env(void);
> > +extern void __init prom_dtb_init_env(void);
> > +extern void __init prom_lefi_init_env(void);
> >  extern void __init szmem(unsigned int node);
> >  extern void *loongson_fdt_blob;
> >
> > diff --git a/arch/mips/loongson64/env.c b/arch/mips/loongson64/env.c
> > index 51a5d050a94c..e7d3a06175e3 100644
> > --- a/arch/mips/loongson64/env.c
> > +++ b/arch/mips/loongson64/env.c
> > @@ -43,7 +43,18 @@ const char *get_system_type(void)
> >  	return "Generic Loongson64 System";
> >  }
> >
> > -void __init prom_init_env(void)
> > +
> > +void __init prom_dtb_init_env(void)
> > +{
> > +	if ((fw_arg2 < CKSEG0 || fw_arg2 > CKSEG1)
> > +		&& (fw_arg2 < XKPHYS || fw_arg2 > XKSEG))
> > +
> > +		loongson_fdt_blob = __dtb_loongson64_2core_2k1000_begin;
> > +	else
> > +		loongson_fdt_blob = (void *)fw_arg2;
> > +}
> > +
> > +void __init prom_lefi_init_env(void)
> >  {
> >  	struct boot_params *boot_p;
> >  	struct loongson_params *loongson_p;
> > diff --git a/arch/mips/loongson64/init.c b/arch/mips/loongson64/init.c
> > index cfa788bca871..ed280b73bf89 100644
> > --- a/arch/mips/loongson64/init.c
> > +++ b/arch/mips/loongson64/init.c
> > @@ -52,6 +52,10 @@ void __init szmem(unsigned int node)
> >  	static unsigned long num_physpages;
> >  	u64 node_id, node_psize, start_pfn, end_pfn, mem_start, mem_size;
> >
> > +	/* Otherwise come from DTB */
> > +	if (loongson_sysconf.fw_interface != LOONGSON_LEFI)
> > +		return;
> > +
> >  	/* Parse memory information and activate */
> >  	for (i = 0; i < loongson_memmap->nr_map; i++) {
> >  		node_id = loongson_memmap->map[i].node_id;
> > @@ -94,12 +98,20 @@ static void __init prom_init_memory(void)
> >  void __init prom_init(void)
> >  {
> >  	fw_init_cmdline();
> > -	prom_init_env();
> > +
> > +	if (fw_arg2 == 0 || (fdt_magic(fw_arg2) == FDT_MAGIC)) {
> > +		loongson_sysconf.fw_interface = LOONGSON_DTB;
> > +		prom_dtb_init_env();
> > +	} else {
> > +		loongson_sysconf.fw_interface = LOONGSON_LEFI;
> > +		prom_lefi_init_env();
> > +	}
> 
> Is it possible to make it compatible with MIPS UHI boot protocol? So 
> boot loaders will be able to
> handle Loongson kernel images as any other MIPS kernel images?

Hmm, as Loongson did many stuff in non-generic manner it's almost impossible :-(
Also their are many devices shipped with current boot protocol.


> 
> This protocol is described here on page 15, "3. Boot protocols"
> https://docplayer.net/62444141-Unified-hosting-interface-md01069-reference-manual.html
> 
> According to this protocol, you should have:
> fw_arg0 = -2
> fw_arg1 = Virtual (kseg0) address of Device Tree Blob
> 
> This would made LS a first grade resident for many boot loaders and 
> save a lot of needles headaches.

Loongson is stepping away from MIPS and it seems like they're going to use EDK-II for their Loongarch.
TBH I've checked Loongson's PMON code and realized it can't be ported to other projects easily.

Tons of unregonized assembly code.


Thanks.

- Jiaxun

> 
> --
> Regards,
> Oleksij
>
Oleksij Rempel March 10, 2021, 1:26 p.m. UTC | #3
Am 10.03.21 um 13:12 schrieb Jiaxun Yang:
>
>
> On Wed, Mar 10, 2021, at 6:57 PM, Oleksij Rempel wrote:
>> Hi,
>>
>> Am 10.03.21 um 08:56 schrieb Qing Zhang:
>>> Add DTB boot support, only support Loongson-2K1000 processor
>>> for now, determine whether to use the built-in DTB or the DTB
>>> from the firmware by checking the range of CKSEG0 and XKPHYS.
>>> loongson_fw_interface will be used in the future.
>>>
>>> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>>> Signed-off-by: Qing Zhang <zhangqing@loongson.cn>
>>> Tested-by: Ming Wang <wangming01@loongson.cn>
>>> ---
>>>
>>> v3-v4: Standard submission of information
>>>        Fix error handling
>>>
>>>  .../include/asm/mach-loongson64/boot_param.h     |  6 ++++++
>>>  arch/mips/include/asm/mach-loongson64/loongson.h |  3 ++-
>>>  arch/mips/loongson64/env.c                       | 13 ++++++++++++-
>>>  arch/mips/loongson64/init.c                      | 16 ++++++++++++++--
>>>  4 files changed, 34 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/arch/mips/include/asm/mach-loongson64/boot_param.h b/arch/mips/include/asm/mach-loongson64/boot_param.h
>>> index 4592841b6b0c..43737401dc06 100644
>>> --- a/arch/mips/include/asm/mach-loongson64/boot_param.h
>>> +++ b/arch/mips/include/asm/mach-loongson64/boot_param.h
>>> @@ -198,7 +198,13 @@ enum loongson_bridge_type {
>>>  	VIRTUAL = 3
>>>  };
>>>
>>> +enum loongson_fw_interface {
>>> +	LOONGSON_LEFI,
>>> +	LOONGSON_DTB,
>>> +};
>>> +
>>>  struct loongson_system_configuration {
>>> +	enum loongson_fw_interface fw_interface;
>>>  	u32 nr_cpus;
>>>  	u32 nr_nodes;
>>>  	int cores_per_node;
>>> diff --git a/arch/mips/include/asm/mach-loongson64/loongson.h b/arch/mips/include/asm/mach-loongson64/loongson.h
>>> index ac1c20e172a2..3f885fa26ba6 100644
>>> --- a/arch/mips/include/asm/mach-loongson64/loongson.h
>>> +++ b/arch/mips/include/asm/mach-loongson64/loongson.h
>>> @@ -23,7 +23,8 @@ extern u32 memsize, highmemsize;
>>>  extern const struct plat_smp_ops loongson3_smp_ops;
>>>
>>>  /* loongson-specific command line, env and memory initialization */
>>> -extern void __init prom_init_env(void);
>>> +extern void __init prom_dtb_init_env(void);
>>> +extern void __init prom_lefi_init_env(void);
>>>  extern void __init szmem(unsigned int node);
>>>  extern void *loongson_fdt_blob;
>>>
>>> diff --git a/arch/mips/loongson64/env.c b/arch/mips/loongson64/env.c
>>> index 51a5d050a94c..e7d3a06175e3 100644
>>> --- a/arch/mips/loongson64/env.c
>>> +++ b/arch/mips/loongson64/env.c
>>> @@ -43,7 +43,18 @@ const char *get_system_type(void)
>>>  	return "Generic Loongson64 System";
>>>  }
>>>
>>> -void __init prom_init_env(void)
>>> +
>>> +void __init prom_dtb_init_env(void)
>>> +{
>>> +	if ((fw_arg2 < CKSEG0 || fw_arg2 > CKSEG1)
>>> +		&& (fw_arg2 < XKPHYS || fw_arg2 > XKSEG))
>>> +
>>> +		loongson_fdt_blob = __dtb_loongson64_2core_2k1000_begin;
>>> +	else
>>> +		loongson_fdt_blob = (void *)fw_arg2;
>>> +}
>>> +
>>> +void __init prom_lefi_init_env(void)
>>>  {
>>>  	struct boot_params *boot_p;
>>>  	struct loongson_params *loongson_p;
>>> diff --git a/arch/mips/loongson64/init.c b/arch/mips/loongson64/init.c
>>> index cfa788bca871..ed280b73bf89 100644
>>> --- a/arch/mips/loongson64/init.c
>>> +++ b/arch/mips/loongson64/init.c
>>> @@ -52,6 +52,10 @@ void __init szmem(unsigned int node)
>>>  	static unsigned long num_physpages;
>>>  	u64 node_id, node_psize, start_pfn, end_pfn, mem_start, mem_size;
>>>
>>> +	/* Otherwise come from DTB */
>>> +	if (loongson_sysconf.fw_interface != LOONGSON_LEFI)
>>> +		return;
>>> +
>>>  	/* Parse memory information and activate */
>>>  	for (i = 0; i < loongson_memmap->nr_map; i++) {
>>>  		node_id = loongson_memmap->map[i].node_id;
>>> @@ -94,12 +98,20 @@ static void __init prom_init_memory(void)
>>>  void __init prom_init(void)
>>>  {
>>>  	fw_init_cmdline();
>>> -	prom_init_env();
>>> +
>>> +	if (fw_arg2 == 0 || (fdt_magic(fw_arg2) == FDT_MAGIC)) {
>>> +		loongson_sysconf.fw_interface = LOONGSON_DTB;
>>> +		prom_dtb_init_env();
>>> +	} else {
>>> +		loongson_sysconf.fw_interface = LOONGSON_LEFI;
>>> +		prom_lefi_init_env();
>>> +	}
>>
>> Is it possible to make it compatible with MIPS UHI boot protocol? So
>> boot loaders will be able to
>> handle Loongson kernel images as any other MIPS kernel images?
>
> Hmm, as Loongson did many stuff in non-generic manner it's almost impossible :-(
> Also their are many devices shipped with current boot protocol.

I would like to understand, why it is impossible. Do fw_arg0 provide memory address or some kind of
count/size? Can it be negative?

We already had same situation with ARM and it was fixed. Why this can't be done for MIPS or LS?

>
>>
>> This protocol is described here on page 15, "3. Boot protocols"
>> https://docplayer.net/62444141-Unified-hosting-interface-md01069-reference-manual.html
>>
>> According to this protocol, you should have:
>> fw_arg0 = -2
>> fw_arg1 = Virtual (kseg0) address of Device Tree Blob
>>
>> This would made LS a first grade resident for many boot loaders and
>> save a lot of needles headaches.
>
> Loongson is stepping away from MIPS and it seems like they're going to use EDK-II for their Loongarch.

It seems to be UEFI related, it seems to be not related to the CPU arch, or do i'm missing something?

In any case, if this is true, then it means, that Loongsoon is about to drop support for old boot
loaders (PMON?) and do new thing (one more boot protocol?). So argumentation, we upstream old own
protocol, but will drop it to make some thing new is not really good example :)

> TBH I've checked Loongson's PMON code and realized it can't be ported to other projects easily.
> Tons of unregonized assembly code.

No need to port it. Here is example of working clean code:
https://git.pengutronix.de/cgit/barebox/tree/arch/mips/boards/loongson-ls1b/lowlevel.S

And this boot loader would boot any

--
Regards,
Oleksij
Oleksij Rempel March 10, 2021, 4:03 p.m. UTC | #4
Am 10.03.21 um 16:58 schrieb Jiaxun Yang:
>
>
> 在 2021/3/10 21:26, Oleksij Rempel 写道:
> [...]
>> I would like to understand, why it is impossible. Do fw_arg0 provide memory address or some kind of
>> count/size? Can it be negative?
>>
>> We already had same situation with ARM and it was fixed. Why this can't be done for MIPS or LS?
>
> Well we can fix it for future MIPS systems but not present Loongson.
>
> Actually I've talked to several Chinese MIPS chip vendors and they
> all agreed to unify the booting protcol.
>
> I raised the same question to Loongson ~3 years ago but got
> negative response.
> The idea got reject in a recent private discussions with Loongson
> about 2K1000 upstream stuff.
>
> Also I realized Loongson's chip comes with too many ISA level
> custom designs which makes it impossible to use MIPS generic
> kernel.
>  
>
>>>> This protocol is described here on page 15, "3. Boot protocols"
>>>> https://docplayer.net/62444141-Unified-hosting-interface-md01069-reference-manual.html
>>>>
>>>> According to this protocol, you should have:
>>>> fw_arg0 = -2
>>>> fw_arg1 = Virtual (kseg0) address of Device Tree Blob
>>>>
>>>> This would made LS a first grade resident for many boot loaders and
>>>> save a lot of needles headaches.
>>>>
>>> Loongson is stepping away from MIPS and it seems like they're going to use EDK-II for their Loongarch.
>>>
>> It seems to be UEFI related, it seems to be not related to the CPU arch, or do i'm missing something?
> I meant they won't invest much to MIPS based chips :-(
>> In any case, if this is true, then it means, that Loongsoon is about to drop support for old boot
>> loaders (PMON?) and do new thing (one more boot protocol?). So argumentation, we upstream old own
>> protocol, but will drop it to make some thing new is not really good example :)
> Yes, actually many new Loongson desktop machines (3A3000/3A4000) are shipped
> with UEFI and relies on second stage bootloader to convert to old boot
> protocol.
>
> I'm againt to upstraming the "new" protocol as it's non-standard UEFI
> with many
> nonsense design.
>
>
>>> TBH I've checked Loongson's PMON code and realized it can't be ported to other projects easily.
>>> Tons of unregonized assembly code.
>>>
>> No need to port it. Here is example of working clean code:
>> https://git.pengutronix.de/cgit/barebox/tree/arch/mips/boards/loongson-ls1b/lowlevel.S
> I've ported U-Boot to LS1C as well. But LS1B/LS1C is Loongson32.
> Loongson64 based systems like LS2K is much more complex than it.
> The bootloader is fullfilled with assembly and mostly undocumented.
> LS2K's PMON contains ~50k lines of assembly.

OK, i hope i'll never have customers using this chips. Are there any
reason why do we wont to keep it alive? :D


--
Regards,
Oleksij
diff mbox series

Patch

diff --git a/arch/mips/include/asm/mach-loongson64/boot_param.h b/arch/mips/include/asm/mach-loongson64/boot_param.h
index 4592841b6b0c..43737401dc06 100644
--- a/arch/mips/include/asm/mach-loongson64/boot_param.h
+++ b/arch/mips/include/asm/mach-loongson64/boot_param.h
@@ -198,7 +198,13 @@  enum loongson_bridge_type {
 	VIRTUAL = 3
 };
 
+enum loongson_fw_interface {
+	LOONGSON_LEFI,
+	LOONGSON_DTB,
+};
+
 struct loongson_system_configuration {
+	enum loongson_fw_interface fw_interface;
 	u32 nr_cpus;
 	u32 nr_nodes;
 	int cores_per_node;
diff --git a/arch/mips/include/asm/mach-loongson64/loongson.h b/arch/mips/include/asm/mach-loongson64/loongson.h
index ac1c20e172a2..3f885fa26ba6 100644
--- a/arch/mips/include/asm/mach-loongson64/loongson.h
+++ b/arch/mips/include/asm/mach-loongson64/loongson.h
@@ -23,7 +23,8 @@  extern u32 memsize, highmemsize;
 extern const struct plat_smp_ops loongson3_smp_ops;
 
 /* loongson-specific command line, env and memory initialization */
-extern void __init prom_init_env(void);
+extern void __init prom_dtb_init_env(void);
+extern void __init prom_lefi_init_env(void);
 extern void __init szmem(unsigned int node);
 extern void *loongson_fdt_blob;
 
diff --git a/arch/mips/loongson64/env.c b/arch/mips/loongson64/env.c
index 51a5d050a94c..e7d3a06175e3 100644
--- a/arch/mips/loongson64/env.c
+++ b/arch/mips/loongson64/env.c
@@ -43,7 +43,18 @@  const char *get_system_type(void)
 	return "Generic Loongson64 System";
 }
 
-void __init prom_init_env(void)
+
+void __init prom_dtb_init_env(void)
+{
+	if ((fw_arg2 < CKSEG0 || fw_arg2 > CKSEG1)
+		&& (fw_arg2 < XKPHYS || fw_arg2 > XKSEG))
+
+		loongson_fdt_blob = __dtb_loongson64_2core_2k1000_begin;
+	else
+		loongson_fdt_blob = (void *)fw_arg2;
+}
+
+void __init prom_lefi_init_env(void)
 {
 	struct boot_params *boot_p;
 	struct loongson_params *loongson_p;
diff --git a/arch/mips/loongson64/init.c b/arch/mips/loongson64/init.c
index cfa788bca871..ed280b73bf89 100644
--- a/arch/mips/loongson64/init.c
+++ b/arch/mips/loongson64/init.c
@@ -52,6 +52,10 @@  void __init szmem(unsigned int node)
 	static unsigned long num_physpages;
 	u64 node_id, node_psize, start_pfn, end_pfn, mem_start, mem_size;
 
+	/* Otherwise come from DTB */
+	if (loongson_sysconf.fw_interface != LOONGSON_LEFI)
+		return;
+
 	/* Parse memory information and activate */
 	for (i = 0; i < loongson_memmap->nr_map; i++) {
 		node_id = loongson_memmap->map[i].node_id;
@@ -94,12 +98,20 @@  static void __init prom_init_memory(void)
 void __init prom_init(void)
 {
 	fw_init_cmdline();
-	prom_init_env();
+
+	if (fw_arg2 == 0 || (fdt_magic(fw_arg2) == FDT_MAGIC)) {
+		loongson_sysconf.fw_interface = LOONGSON_DTB;
+		prom_dtb_init_env();
+	} else {
+		loongson_sysconf.fw_interface = LOONGSON_LEFI;
+		prom_lefi_init_env();
+	}
 
 	/* init base address of io space */
 	set_io_port_base(PCI_IOBASE);
 
-	loongson_sysconf.early_config();
+	if (loongson_sysconf.early_config)
+		loongson_sysconf.early_config();
 
 #ifdef CONFIG_NUMA
 	prom_init_numa_memory();