[U-Boot-Users] [Fwd: [PATCH] Add Uboot ASMP suport for MPC8641D]
Jon Loeliger
jdl at freescale.com
Wed Mar 21 16:08:16 CET 2007
Kumar,
As I indicated to you on IRC a few days ago, here is the
U-Boot patch to support Asymmetric Multi-Processors on 8641 HPCN.
This corresponds to the patch I also just posted to the
linuxppc-dev list as well.
jdl
From: Haiying Wang <Haiying.Wang at freescale.com>
Subject: [PATCH] Add Uboot ASMP suport for MPC8641D
Date: Mon, 26 Feb 2007 15:51:27 -0500
1. Core1 low memeory translate mode is enabled, so both cores have private 256M byte memory.
2. Core0 kicks off core1 at the end of board_init_r. Both cores can run independently then.
3.TSEC1/2, Uart0, PCIe are assigned to core0 and TSEC3/4, Uart1 are assigned to core1.
Signed-off-by: Haiying Wang <Haiying.Wang at freescale.com>
Signed-off-by: Xianghua Xiao <X.Xiao at freescale.com>
---
board/mpc8641hpcn/mpc8641hpcn.c | 6 ++++++
common/ft_build.c | 10 +++++++++-
cpu/mpc86xx/interrupts.c | 9 +++++++++
cpu/mpc86xx/start.S | 10 +++++++++-
drivers/serial.c | 29 +++++++++++++++++++++++++++++
drivers/tsec.c | 17 +++++++++++++++++
include/asm-ppc/global_data.h | 3 +++
include/configs/MPC8641HPCN.h | 11 ++++++++++-
lib_ppc/board.c | 31 +++++++++++++++++++++++++++++++
net/eth.c | 9 +++++++++
10 files changed, 132 insertions(+), 3 deletions(-)
diff --git a/board/mpc8641hpcn/mpc8641hpcn.c b/board/mpc8641hpcn/mpc8641hpcn.c
index 1d67365..861130e 100644
--- a/board/mpc8641hpcn/mpc8641hpcn.c
+++ b/board/mpc8641hpcn/mpc8641hpcn.c
@@ -99,6 +99,12 @@ initdram(int board_type)
{
long dram_size = 0;
+#ifdef CONFIG_ASMP
+ DECLARE_GLOBAL_DATA_PTR;
+ if (gd->pir == 1)
+ return CONFIG_ASMP_RAM_SIZE;
+#endif
+
#if defined(CONFIG_SPD_EEPROM)
dram_size = spd_sdram();
#else
diff --git a/common/ft_build.c b/common/ft_build.c
index 980e40f..679aaf1 100644
--- a/common/ft_build.c
+++ b/common/ft_build.c
@@ -522,10 +522,18 @@ void ft_setup(void *blob, bd_t * bd, ulong initrd_start, ulong initrd_end)
ft_prop_int(&cxt, "linux,initrd-start", initrd_start);
ft_prop_int(&cxt, "linux,initrd-end", initrd_end);
}
+
+#ifdef CONFIG_ASMP
+ DECLARE_GLOBAL_DATA_PTR;
+ if (gd->pir == 1)
+ ft_prop_str(&cxt, "linux, stdout-path", OF_STDOUT_CORE1_PATH);
+ else
+ ft_prop_str(&cxt, "linux, stdout-path", OF_STDOUT_PATH);
+#else
#ifdef OF_STDOUT_PATH
ft_prop_str(&cxt, "linux,stdout-path", OF_STDOUT_PATH);
#endif
-
+#endif
ft_end_node(&cxt);
ft_end_node(&cxt); /* end root */
diff --git a/cpu/mpc86xx/interrupts.c b/cpu/mpc86xx/interrupts.c
index 49820bb..bf910cc 100644
--- a/cpu/mpc86xx/interrupts.c
+++ b/cpu/mpc86xx/interrupts.c
@@ -95,9 +95,18 @@ int interrupt_init(void)
*/
if ((get_svr() & 0xf0) == 0x20) {
volatile immap_t *immr = (immap_t *)CFG_IMMR;
+#ifdef CONFIG_ASMP
+ DECLARE_GLOBAL_DATA_PTR;
+ if (gd->pir == 0) {
+ immr->im_pic.gcr = MPC86xx_PICGCR_RST;
+ while (immr->im_pic.gcr & MPC86xx_PICGCR_RST);
+ immr->im_pic.gcr = MPC86xx_PICGCR_MODE;
+ }
+#else
immr->im_pic.gcr = MPC86xx_PICGCR_RST;
while (immr->im_pic.gcr & MPC86xx_PICGCR_RST);
immr->im_pic.gcr = MPC86xx_PICGCR_MODE;
+#endif
}
/* call cpu specific function from $(CPU)/interrupts.c */
diff --git a/cpu/mpc86xx/start.S b/cpu/mpc86xx/start.S
index 2b0f0be..9f7e361 100644
--- a/cpu/mpc86xx/start.S
+++ b/cpu/mpc86xx/start.S
@@ -192,8 +192,10 @@ boot_warm:
mtspr PIR, r0
beq 1f
+#if !defined(CONFIG_ASMP)
bl secondary_cpu_setup
#endif
+#endif
/* disable everything */
1: li r0, 0
@@ -236,6 +238,12 @@ in_flash:
bl setup_bats
sync
+#ifdef CONFIG_ASMP
+ mfspr r0, PIR
+ cmpwi r0, 0
+ bne 2f
+#endif
+
#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR)
/* setup ccsrbar */
bl setup_ccsrbar
@@ -312,7 +320,7 @@ in_flash:
*/
/* enable address translation */
- bl enable_addr_trans
+2: bl enable_addr_trans
sync
/* enable and invalidate the data cache */
diff --git a/drivers/serial.c b/drivers/serial.c
index 76425d8..15cf0ae 100644
--- a/drivers/serial.c
+++ b/drivers/serial.c
@@ -153,6 +153,11 @@ int serial_init (void)
{
int clock_divisor;
+#ifdef CONFIG_ASMP
+ if (gd->pir ==1)
+ return 0;
+#endif
+
#ifdef CFG_NS87308
initialise_ns87308();
#endif
@@ -233,7 +238,11 @@ serial_putc_dev(unsigned int dev_index,const char c)
void
serial_putc(const char c)
{
+#ifdef CONFIG_ASMP
+ _serial_putc(c,CONFIG_CONS_INDEX + gd->pir);
+#else
_serial_putc(c,CONFIG_CONS_INDEX);
+#endif
}
#endif
@@ -247,7 +256,11 @@ serial_putc_raw_dev(unsigned int dev_index,const char c)
void
serial_putc_raw(const char c)
{
+#ifdef CONFIG_ASMP
+ _serial_putc_raw(c,CONFIG_CONS_INDEX + gd->pir);
+#else
_serial_putc_raw(c,CONFIG_CONS_INDEX);
+#endif
}
#endif
@@ -261,7 +274,11 @@ serial_puts_dev(unsigned int dev_index,const char *s)
void
serial_puts(const char *s)
{
+#ifdef CONFIG_ASMP
+ _serial_puts(s,CONFIG_CONS_INDEX + gd->pir);
+#else
_serial_puts(s,CONFIG_CONS_INDEX);
+#endif
}
#endif
@@ -275,7 +292,11 @@ serial_getc_dev(unsigned int dev_index)
int
serial_getc(void)
{
+#ifdef CONFIG_ASMP
+ return _serial_getc(CONFIG_CONS_INDEX + gd->pir);
+#else
return _serial_getc(CONFIG_CONS_INDEX);
+#endif
}
#endif
@@ -289,7 +310,11 @@ serial_tstc_dev(unsigned int dev_index)
int
serial_tstc(void)
{
+#ifdef CONFIG_ASMP
+ return _serial_tstc(CONFIG_CONS_INDEX + gd->pir);
+#else
return _serial_tstc(CONFIG_CONS_INDEX);
+#endif
}
#endif
@@ -303,7 +328,11 @@ serial_setbrg_dev(unsigned int dev_index)
void
serial_setbrg(void)
{
+#ifdef CONFIG_ASMP
+ _serial_setbrg(CONFIG_CONS_INDEX + gd->pir);
+#else
_serial_setbrg(CONFIG_CONS_INDEX);
+#endif
}
#endif
diff --git a/drivers/tsec.c b/drivers/tsec.c
index 8edfc8c..0be3bf7 100644
--- a/drivers/tsec.c
+++ b/drivers/tsec.c
@@ -683,6 +683,18 @@ static void startup_tsec(struct eth_device *dev)
struct tsec_private *priv = (struct tsec_private *)dev->priv;
volatile tsec_t *regs = priv->regs;
+#ifdef CONFIG_ASMP
+ /* Point to the buffer descriptors */
+ regs->tbase = (unsigned int)(&rtx.txbd[txIdx]) + 0x10000000 * gd->pir;
+ regs->rbase = (unsigned int)(&rtx.rxbd[rxIdx]) + 0x10000000 * gd->pir;
+
+ /* Initialize the Rx Buffer descriptors */
+ for (i = 0; i < PKTBUFSRX; i++) {
+ rtx.rxbd[i].status = RXBD_EMPTY;
+ rtx.rxbd[i].length = 0;
+ rtx.rxbd[i].bufPtr = (uint) NetRxPackets[i] + 0x10000000 * gd->pir;
+ }
+#else
/* Point to the buffer descriptors */
regs->tbase = (unsigned int)(&rtx.txbd[txIdx]);
regs->rbase = (unsigned int)(&rtx.rxbd[rxIdx]);
@@ -693,6 +705,7 @@ static void startup_tsec(struct eth_device *dev)
rtx.rxbd[i].length = 0;
rtx.rxbd[i].bufPtr = (uint) NetRxPackets[i];
}
+#endif
rtx.rxbd[PKTBUFSRX - 1].status |= RXBD_WRAP;
/* Initialize the TX Buffer Descriptors */
@@ -737,7 +750,11 @@ static int tsec_send(struct eth_device *dev, volatile void *packet, int length)
}
}
+#ifdef CONFIG_ASMP
+ rtx.txbd[txIdx].bufPtr = (uint) packet + 0x10000000 * gd->pir;
+#else
rtx.txbd[txIdx].bufPtr = (uint) packet;
+#endif
rtx.txbd[txIdx].length = length;
rtx.txbd[txIdx].status |=
(TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT);
diff --git a/include/asm-ppc/global_data.h b/include/asm-ppc/global_data.h
index 8bc61b6..e2d003b 100644
--- a/include/asm-ppc/global_data.h
+++ b/include/asm-ppc/global_data.h
@@ -127,6 +127,9 @@ typedef struct global_data {
#ifdef CONFIG_LWMON
unsigned long kbd_status;
#endif
+#ifdef CONFIG_ASMP
+ unsigned long pir;
+#endif
void **jt; /* jump table */
} gd_t;
diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h
index f663d72..018da3e 100644
--- a/include/configs/MPC8641HPCN.h
+++ b/include/configs/MPC8641HPCN.h
@@ -46,7 +46,12 @@
#define CFG_RESET_ADDRESS 0xfff00100
-/*#undef CONFIG_PCI*/
+#define CONFIG_ASMP
+#ifdef CONFIG_ASMP
+#define CONFIG_ASMP_RAM_SIZE 0x10000000
+#define OF_STDOUT_CORE1_PATH "/soc8641 at f8000000/serial at 4600"
+#endif
+
#define CONFIG_PCI
#define CONFIG_TSEC_ENET /* tsec ethernet support */
@@ -397,7 +402,11 @@
* 0x0000_0000 2G DDR
*/
#define CFG_DBAT0L (BATL_PP_RW | BATL_MEMCOHERENCE)
+#ifdef CONFIG_ASMP
+#define CFG_DBAT0U (BATU_BL_512M | BATU_VS | BATU_VP)
+#else
#define CFG_DBAT0U (BATU_BL_2G | BATU_VS | BATU_VP)
+#endif
#define CFG_IBAT0L (BATL_PP_RW | BATL_MEMCOHERENCE )
#define CFG_IBAT0U CFG_DBAT0U
diff --git a/lib_ppc/board.c b/lib_ppc/board.c
index 24e8e97..c517390 100644
--- a/lib_ppc/board.c
+++ b/lib_ppc/board.c
@@ -71,6 +71,10 @@
#ifdef CONFIG_PS2KBD
#include <keyboard.h>
#endif
+#ifdef CONFIG_ASMP
+#include <asm/processor.h>
+#include <asm/io.h>
+#endif
#ifdef CFG_UPDATE_FLASH_SIZE
extern int update_flash_size (int flash_size);
@@ -223,6 +227,9 @@ static int init_func_ram (void)
puts ("DRAM: ");
if ((gd->ram_size = initdram (board_type)) > 0) {
+#ifdef CONFIG_ASMP
+ gd->ram_size = CONFIG_ASMP_RAM_SIZE;
+#endif
print_size (gd->ram_size, "");
#ifdef CONFIG_ADD_RAM_INFO
board_add_ram_info(0);
@@ -385,6 +392,10 @@ void board_init_f (ulong bootflag)
memset ((void *) gd, 0, sizeof (gd_t));
#endif
+#ifdef CONFIG_ASMP
+ gd->pir = mfspr(PIR);
+#endif
+
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr) () != 0) {
hang ();
@@ -907,11 +918,16 @@ void board_init_r (gd_t *id, ulong dest_addr)
WATCHDOG_RESET ();
#if defined(CONFIG_PCI) && !defined(CONFIG_BAB7xx) && !defined(CONFIG_CPC45)
+#ifdef CONFIG_ASMP
+ if (gd->pir == 0)
+ pci_init();
+#else
/*
* Do pci configuration
*/
pci_init ();
#endif
+#endif
/** leave this here (after malloc(), environment and PCI are working) **/
/* Initialize devices */
@@ -984,10 +1000,17 @@ void board_init_r (gd_t *id, ulong dest_addr)
WATCHDOG_RESET ();
#if (CONFIG_COMMANDS & CFG_CMD_SCSI)
+#ifdef CONFIG_ASMP
+ if (gd->pir == 0)
+ WATCHDOG_RESET ();
+ puts ("SCSI: ");
+ scsi_init ();
+#else
WATCHDOG_RESET ();
puts ("SCSI: ");
scsi_init ();
#endif
+#endif
#if (CONFIG_COMMANDS & CFG_CMD_DOC)
WATCHDOG_RESET ();
@@ -1104,6 +1127,14 @@ void board_init_r (gd_t *id, ulong dest_addr)
}
#endif
+#ifdef CONFIG_ASMP
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile ccsr_local_mcm_t *mcm = &immap->im_local_mcm;
+ if(gd->pir == 0)
+ /* kick off core1 */
+ mcm->pcr |= 1 << (1 + 24);
+#endif
+
/* Initialization complete - start the monitor */
/* main_loop() can return to retry autoboot, if so just run it again. */
diff --git a/net/eth.c b/net/eth.c
index cca9392..964c5ef 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -200,6 +200,14 @@ int eth_initialize(bd_t *bis)
#if defined(CONFIG_UEC_ETH2)
uec_initialize(1);
#endif
+#ifdef CONFIG_ASMP
+ DECLARE_GLOBAL_DATA_PTR;
+ char tsec_name[10];
+ for (i = 0; i < 2; i++) {
+ sprintf(tsec_name, "eTSEC%d", (gd->pir * 2 + 1 + i));
+ tsec_initialize(bis, (gd->pir * 2 + i), tsec_name);
+ }
+#else
#if defined(CONFIG_MPC86XX_TSEC1)
tsec_initialize(bis, 0, CONFIG_MPC86XX_TSEC1_NAME);
#endif
@@ -215,6 +223,7 @@ int eth_initialize(bd_t *bis)
#if defined(CONFIG_MPC86XX_TSEC4)
tsec_initialize(bis, 3, CONFIG_MPC86XX_TSEC4_NAME);
#endif
+#endif
#if defined(FEC_ENET) || defined(CONFIG_ETHER_ON_FCC)
fec_initialize(bis);
--
1.4.4.4
More information about the U-Boot
mailing list