[MPC8272ADS] porting a custom patch from 2.6.21.7 to 2.6.35.7 for a custom board

Alexandru Ionut Grama gramaalexandruionut at gmail.com
Sat Oct 30 01:09:10 EST 2010


Hello linuxppc-dev community!

First of all, I want to introduce myself and my project. I'm working at the
Technical University of Madrid in a project for porting Linux to an embedded
system, a router. This project is my final degree thesis. This machine has a
MPC8272VRMIBA processor and a custom platform and seems to be based on
MPC8272ADS. The company that subsidizes us provides us a patch for making
the router compatible with Linux, but it only works for Linux-2.6.21.

I've achieve some aims, but for now I want to make openssl compatible with
SEC1.0. I want to use the Cryptographic-API with talitos to get the
advantage of using crypto-processor. I've decided to use Linux-2.6.35.7
because is the latest stable version of Linux, and adds new features to
"talitos". So, for now, my aim is to port the original patch to
Linux-2.6.35.7 to get CPM and serial port compatibility. After that I can do
kernel debugging for making Ethernet cards compatible, and finally make some
benchmark for the crypto system. The bad point is that the architecture of
kernel's code changes a lot and I don't know if the changes that I'm doing
are in the good way.

I'll try to explain my best what I'm doing.

Here is the original change:

diff -rcNP linux-2.6.21/arch/powerpc/mm/init_32.c
atlas_kernel/arch/powerpc/mm/init_32.c
*** linux-2.6.21/arch/powerpc/mm/init_32.c  2007-04-26 05:08:32.000000000
+0200
--- atlas_kernel/arch/powerpc/mm/init_32.c  2008-04-24 08:43:51.000000000
+0200
***************
*** 172,178 ****
  #ifdef CONFIG_HIGHMEM
    ioremap_base = PKMAP_BASE;
  #else
!   ioremap_base = 0xfe000000UL;    /* for now, could be 0xfffff000 */
  #endif /* CONFIG_HIGHMEM */
    ioremap_bot = ioremap_base;

--- 172,178 ----
  #ifdef CONFIG_HIGHMEM
    ioremap_base = PKMAP_BASE;
  #else
!   ioremap_base = 0xff000000UL;    /* for now, could be 0xfffff000 */ /*
gonza */
  #endif /* CONFIG_HIGHMEM */
    ioremap_bot = ioremap_base;

I reproduce this change with this:

diff -rc linux-2.6.35.7/arch/powerpc/include/asm/pgtable-ppc32.h
linux-agrama/arch/powerpc/include/asm/pgtable-ppc32.h
*** linux-2.6.35.7/arch/powerpc/include/asm/pgtable-ppc32.h 2010-09-29
03:09:08.000000000 +0200
--- linux-agrama/arch/powerpc/include/asm/pgtable-ppc32.h   2010-10-26
18:47:28.000000000 +0200
***************pq2ads
*** 63,69 ****
  #ifdef CONFIG_HIGHMEM
  #define KVIRT_TOP PKMAP_BASE
  #else
! #define KVIRT_TOP (0xfe000000UL)  /* for now, could be FIXMAP_BASE ? */
  #endif

  /*
--- 63,69 ----
  #ifdef CONFIG_HIGHMEM
  #define KVIRT_TOP PKMAP_BASE
  #else
! #define KVIRT_TOP (0xff000000UL)  /* for now, could be FIXMAP_BASE ? */ /*
agrama, antes KVIRT_TOP era 0xfe000000UL */
  #endif

  /*

Also, I've add the next line:

diff -rc linux-2.6.35.7/arch/powerpc/mm/init_32.c
linux-agrama/arch/powerpc/mm/init_32.c
*** linux-2.6.35.7/arch/powerpc/mm/init_32.c    2010-09-29
03:09:08.000000000 +0200
--- linux-agrama/arch/powerpc/mm/init_32.c  2010-10-29 10:28:43.000000000
+0200
***************
*** 178,184 ****

    /* Initialize early top-down ioremap allocator */
    ioremap_bot = IOREMAP_TOP;
!
    /* Map in I/O resources */
    if (ppc_md.progress)
        ppc_md.progress("MMU:setio", 0x302);
--- 178,184 ----

    /* Initialize early top-down ioremap allocator */
    ioremap_bot = IOREMAP_TOP;
!   ioremap_base = ioremap_bot; /*agrama*/
    /* Map in I/O resources */
    if (ppc_md.progress)
        ppc_md.progress("MMU:setio", 0x302);

¿It's correct to add the line ioremap_base=ioremap_bot or ioremap_base it
not used anymore?

The next change it's about a jam on pci's kref. This line has been deleted
on 2.6.21:

diff -rcNP linux-2.6.21/arch/powerpc/platforms/82xx/mpc82xx_ads.c
atlas_kernel/arch/powerpc/platforms/82xx/mpc82xx_ads.c
*** linux-2.6.21/arch/powerpc/platforms/82xx/mpc82xx_ads.c  2007-04-26
05:08:32.000000000 +0200
--- atlas_kernel/arch/powerpc/platforms/82xx/mpc82xx_ads.c  2008-04-24
08:43:51.000000000 +0200
***************
*** 533,539 ****
        return;
    }
    pci_clk_frq = *(uint *) ptr;
-   of_node_put(np);
    bus_range = get_property(np, "bus-range", &len);
    if (bus_range == NULL || len < 2 * sizeof(int)) {
        printk(KERN_WARNING "Can't get bus-range for %s, assume"

I didn't find an equivalent operation on 2.6.35 because the code has been
changed completly. ¿Where it's included this operation about the bus?

Here there's a change of the macro CPM_BASE_ADDR :

diff -rcNP linux-2.6.21/arch/powerpc/platforms/82xx/pq2ads.h
atlas_kernel/arch/powerpc/platforms/82xx/pq2ads.h
*** linux-2.6.21/arch/powerpc/platforms/82xx/pq2ads.h   2007-04-26
05:08:32.000000000 +0200
--- atlas_kernel/arch/powerpc/platforms/82xx/pq2ads.h   2008-04-24
08:43:51.000000000 +0200
***************
*** 30,36 ****
  #define CPUINFO_MACHINE       "PQ2 ADS PowerPC"

  /* Backword-compatibility stuff for the drivers */
! #define CPM_MAP_ADDR      ((uint)0xf0000000)
  #define CPM_IRQ_OFFSET 0

  /* The ADS8260 has 16, 32-bit wide control/status registers, accessed
--- 30,36 ----
  #define CPUINFO_MACHINE       "PQ2 ADS PowerPC"

  /* Backword-compatibility stuff for the drivers */
! #define CPM_MAP_ADDR      ((uint)0xff000000)  /*gonza*/
  #define CPM_IRQ_OFFSET 0

It's seems that it has to be 0xff000000, but in 2.6.35 this symbol it's not
used anymore. ¿Where it's defined right now, or how I can handle this
address? I need it for the next part, that it's the hardest one to modify.

Here comes the hardest part at the file
arch/powerpc/platforms/82xx/mpc82xx_ads.c:
***************
*** 632,637 ****
--- 632,643 ----
    while (1) ;
  }

+ static void __init m82xx_map_io(void)   /* gonza */
+ {
+     io_block_mapping(CPM_MAP_ADDR, CPM_MAP_ADDR, ((uint)(4 * 64 * 1024)),
_PAGE_IO);
+ }
+
+
  define_machine(mpc82xx_ads)
  {
    .name = "MPC82xx ADS",
***************
*** 642,645 ****
--- 648,652 ----
    .get_irq =    cpm2_get_irq,
    .calibrate_decr =    m82xx_calibrate_decr,
    .restart = m82xx_restart,.halt = m82xx_halt,
+   .setup_io_mappings =    m82xx_map_io, /* gonza */
  };

Here it's a modification that sets the base address for CPM with
io_block_mapping. I've seen in another discussion that io_block_mapping it's
became deprecated and it's out or kernel code. Does ioremap() function
became smarter and you can use it instead of io_block_mapping? I've found
some part of the code that I think do the same stuff, but it's not seems
working. Also, I've tried with setbat() changing the addresses for
0xff000000, but it doesn't work. Also, I've removed the original setbat line
and let only mine. So it doesn't work with the both lines or letting only
mine (being ioremap() or setbat()).
*** linux-2.6.35.7/arch/powerpc/sysdev/cpm_common.c    2010-09-29
03:09:08.000000000 +0200
--- linux-agrama/arch/powerpc/sysdev/cpm_common.c    2010-10-29
13:20:35.000000000 +0200
***************
*** 58,63 ****
--- 58,64 ----
      if (cpm_udbg_txdesc) {
  #ifdef CONFIG_CPM2
          setbat(1, 0xf0000000, 0xf0000000, 1024*1024, PAGE_KERNEL_NCG);
+         ioremap(((uint)0xff000000UL),(uint)1024*64*4);
  #endif
          udbg_putc = udbg_putc_cpm;
      }

I've seen that .setup_io_mappings was removed from kernel code. It has beed
called in version 2.6.21.7 from arch/powerpc/mm/init_32.c. It's has the same
effect make this operation at arch/powerpc/sysdev/cpm_common.c ? Which
operation should I do, ioremap(),setbat() or another one?

The last part of the modification it's about the serial port. At the version
2.6.21.7 you can choose where it's connected the serial port
(SCC1,SCC2,SCC3,SCC4,SMC1 or SMC2). Our serial port it's connected over
SMC1. We define it with the var SERIAL_CPM_SMC1 at menuconfig. At the
2.6.35.7 there's no option for do that. How should i do to force the serial
on SMC1? Also, there's a change when you init the serial port:
diff -rcNP linux-2.6.21/drivers/serial/cpm_uart/cpm_uart_cpm2.c
atlas_kernel/drivers/serial/cpm_uart/cpm_uart_cpm2.c
*** linux-2.6.21/drivers/serial/cpm_uart/cpm_uart_cpm2.c    2007-04-26
05:08:32.000000000 +0200
--- atlas_kernel/drivers/serial/cpm_uart/cpm_uart_cpm2.c    2008-04-24
08:43:52.000000000 +0200
***************
*** 95,105 ****
    volatile iop_cpm2_t *io = cpm2_map(im_ioport);
    volatile cpmux_t *cpmux = cpm2_map(im_cpmux);

!   /* SMC1 is only on port D */
!   io->iop_ppard |= 0x00c00000;
!   io->iop_pdird |= 0x00400000;
!   io->iop_pdird &= ~0x00800000;
!   io->iop_psord &= ~0x00c00000;

    /* Wire BRG1 to SMC1 */
    cpmux->cmx_smr &= 0x0f;
--- 95,105 ----
    volatile iop_cpm2_t *io = cpm2_map(im_ioport);
    volatile cpmux_t *cpmux = cpm2_map(im_cpmux);

! /* gonza, se cambia ppard por pparc*/
!   io->iop_pparc |= 0x0c000000;
!   io->iop_pdirc |= 0x04000000;
!   io->iop_pdirc &= ~0x08000000;
!   io->iop_psorc &= ~0x0c000000;

    /* Wire BRG1 to SMC1 */
    cpmux->cmx_smr &= 0x0f;

The change consists on use port c instead of port d. Also, the values that
are written are multiplied of 0x10. In version 2.6.35.7 I've made the next
change that I believe that makes the same stuff:
diff -rc linux-2.6.35.7/arch/powerpc/platforms/82xx/mpc8272_ads.c
linux-agrama/arch/powerpc/platforms/82xx/mpc8272_ads.c
*** linux-2.6.35.7/arch/powerpc/platforms/82xx/mpc8272_ads.c    2010-09-29
03:09:08.000000000 +0200
--- linux-agrama/arch/powerpc/platforms/82xx/mpc8272_ads.c  2010-10-28
15:05:49.000000000 +0200
***************
*** 108,113 ****
--- 108,127 ----
    {3, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
    {3, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY},
    {3, 25, CPM_PIN_INPUT | CPM_PIN_PRIMARY},
+
+ #if 0 /* agrama */
+   /* En linux-2.6.21.7 (atlas):*/
+   /* gonza, se cambia ppard por pparc*/
+   io->iop_pparc |= 0x0c 00 00 00;
+   1100
+   io->iop_pdirc |= 0x04000000;
+   io->iop_pdirc &= ~0x08000000;
+   io->iop_psorc &= ~0x0c000000;
+ #endif
+
+     /* SMC1 */    /* agrama */
+       {2, 26, (0*CPM_PIN_GPIO) | CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, /*
agrama */
+       {2, 27, (0*CPM_PIN_GPIO) | CPM_PIN_INPUT  | CPM_PIN_SECONDARY}, /*
agrama */
  };

There's another modification in version 2.6.21.7 about Ethernet, but I
believe that doesn't affect to serial port.

diff -rcNP linux-2.6.21/arch/powerpc/sysdev/fsl_soc.c
atlas_kernel/arch/powerpc/sysdev/fsl_soc.c
*** linux-2.6.21/arch/powerpc/sysdev/fsl_soc.c  2007-04-26
05:08:32.000000000 +0200
--- atlas_kernel/arch/powerpc/sysdev/fsl_soc.c  2008-04-24
08:43:51.000000000 +0200
***************
*** 679,685 ****
            fs_enet_data.rx_ring = 32;
            fs_enet_data.tx_ring = 32;
            fs_enet_data.rx_copybreak = 240;
!           fs_enet_data.use_napi = 0;
            fs_enet_data.napi_weight = 17;
            fs_enet_data.mem_offset = FCC_MEM_OFFSET(fcc_index);
            fs_enet_data.cp_page = CPM_CR_FCC_PAGE(fcc_index);
--- 680,686 ----
            fs_enet_data.rx_ring = 32;
            fs_enet_data.tx_ring = 32;
            fs_enet_data.rx_copybreak = 240;
!           fs_enet_data.use_napi = 1;
            fs_enet_data.napi_weight = 17;
            fs_enet_data.mem_offset = FCC_MEM_OFFSET(fcc_index);
            fs_enet_data.cp_page = CPM_CR_FCC_PAGE(fcc_index);
***************
*** 713,731 ****
                fs_enet_mdio_bb_data.delay =
                    mdio_bb_prop[5];

                fs_enet_mdio_bb_data.irq[0] = phy_irq[0];
                fs_enet_mdio_bb_data.irq[1] = -1;
                fs_enet_mdio_bb_data.irq[2] = -1;
                fs_enet_mdio_bb_data.irq[3] = phy_irq[0];
                fs_enet_mdio_bb_data.irq[31] = -1;

                fs_enet_mdio_bb_data.mdio_dat.offset =
                    (u32)&cpm2_immr->im_ioport.iop_pdatc;
                fs_enet_mdio_bb_data.mdio_dir.offset =
                    (u32)&cpm2_immr->im_ioport.iop_pdirc;
                fs_enet_mdio_bb_data.mdc_dat.offset =
                    (u32)&cpm2_immr->im_ioport.iop_pdatc;
!
                ret = platform_device_add_data(
                        fs_enet_mdio_bb_dev,
                        &fs_enet_mdio_bb_data,
--- 714,747 ----
                fs_enet_mdio_bb_data.delay =
                    mdio_bb_prop[5];
+ /*gonza: Creo que aqui se esta suponiendo que hay phy con direccion 0 y
3*/
+ /*igual que en mii-bitbang.c*/
                fs_enet_mdio_bb_data.irq[0] = phy_irq[0];
                fs_enet_mdio_bb_data.irq[1] = -1;
                fs_enet_mdio_bb_data.irq[2] = -1;
                fs_enet_mdio_bb_data.irq[3] = phy_irq[0];
                fs_enet_mdio_bb_data.irq[31] = -1;

+                 /*gonza: uso los campos mdio_port y mdc_port que son
0=PORTA..3=PORTD*/
+                 offset_port_port = (u32)&cpm2_immr->im_ioport.iop_pdirb -
(u32)&cpm2_immr->im_ioport.iop_pdira;
+
+               fs_enet_mdio_bb_data.mdio_dat.offset =
+                       (u32)&cpm2_immr->im_ioport.iop_pdata +
+                       (offset_port_port * fs_enet_mdio_bb_data.mdio_port);
+               fs_enet_mdio_bb_data.mdio_dir.offset =
+                       (u32)&cpm2_immr->im_ioport.iop_pdira +
+                       (offset_port_port * fs_enet_mdio_bb_data.mdio_port);
+               fs_enet_mdio_bb_data.mdc_dat.offset =
+                       (u32)&cpm2_immr->im_ioport.iop_pdata +
+                       (offset_port_port * fs_enet_mdio_bb_data.mdc_port);
+ #if 0
                fs_enet_mdio_bb_data.mdio_dat.offset =
                    (u32)&cpm2_immr->im_ioport.iop_pdatc;
                fs_enet_mdio_bb_data.mdio_dir.offset =
                    (u32)&cpm2_immr->im_ioport.iop_pdirc;
                fs_enet_mdio_bb_data.mdc_dat.offset =
                    (u32)&cpm2_immr->im_ioport.iop_pdatc;
! #endif
                ret = platform_device_add_data(
                        fs_enet_mdio_bb_dev,
                        &fs_enet_mdio_bb_data,
***************
*** 733,739 ****
                if (ret)
                    goto unreg;
            }
!
            of_node_put(phy);
            of_node_put(mdio);

--- 749,755 ----
                if (ret)
                    goto unreg;
            }
!
            of_node_put(phy);
            of_node_put(mdio);

***************
*** 754,759 ****
--- 770,777 ----

  arch_initcall(fs_enet_of_init);

+ #if 0 /* gonza */
+
  static const char scc_regs[] = "regs";
  static const char scc_pram[] = "pram";

***************
*** 828,833 ****
--- 846,853 ----
  }

  arch_initcall(cpm_uart_of_init);
+ #endif
+
  #endif /* CONFIG_CPM2 */

  #ifdef CONFIG_8xx
***************
*** 1022,1027 ****
--- 1042,1050 ----

  arch_initcall(fs_enet_of_init);

+ #endif /* CONFIG_8xx */
+
+ #if defined(CONFIG_CPM2) || defined(CONFIG_8xx)

  static const char *smc_regs = "regs";
  static const char *smc_pram = "pram";
***************
*** 1096,1099 ****

  arch_initcall(cpm_smc_uart_of_init);

! #endif /* CONFIG_8xx */
--- 1119,1122 ----

  arch_initcall(cpm_smc_uart_of_init);

! #endif /* CONFIG_CPM2 || CONFIG_8xx */

So, the questions are the next:
- linux-2.6.21/arch/powerpc/mm/init_32.c
linux-2.6.35.7/arch/powerpc/mm/pgtable_32.h
   - It's ok what I'm doing changing here KVIRT_TOP?
   - ioremap_base = ioremap_bot at linux-2.6.35.7/arch/powerpc/mm/init_32.c?
- linux-2.6.21/arch/powerpc/platforms/82xx/pq2ads.h
   - Where and how can I define CMP_MAP_ADDR, that all the controllers can
use it?
   - Changing the CMP_MAP_ADDR in 2.6.21.7 involves that I should use a
configuration for 2.6.35 based on PQ2ADS?
-linux-2.6.35.7/arch/powerpc/platforms/82xx/mpc8272_ads.c
   - How shall I the same stuff asociated to the operation
.setup_io_mappings, that uses block_io_mapping?
-linux-2.6.35.7/drivers/serial/cpm_uart/cpm_uart_cpm2.c
   - How shall I force the uart driver to work on SMC1?
   - What shall I change to make the same operation at recognizing the uart,
(I mean, asingn control sequences to iop_pparc,iop_pdirc and iop_psorc), in
the new "style" of kernel architecture?
-linux-2.6.21/arch/powerpc/sysdev/fsl_soc.c
   -This code it's necesary for making the UART works properly?

I really appreciate the work that you're doing adding features to the new
kernel, but it's very obscure for me to make the changes that I need, so
I'll apreciate very much your help with my issue. Also I think that it's a
very good way to show to the begginers (as me) how to make the proper
changes with the new style of the code.

King regards,
Alexandru
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ozlabs.org/pipermail/linuxppc-dev/attachments/20101029/ef67eb2f/attachment-0001.html>


More information about the Linuxppc-dev mailing list