1debd1f3cSChristophe Leroy /* 2debd1f3cSChristophe Leroy * (C) Copyright 2000-2003 3debd1f3cSChristophe Leroy * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4debd1f3cSChristophe Leroy * 5debd1f3cSChristophe Leroy * SPDX-License-Identifier: GPL-2.0+ 6debd1f3cSChristophe Leroy */ 7debd1f3cSChristophe Leroy 8debd1f3cSChristophe Leroy /* 9debd1f3cSChristophe Leroy * MPC8xx Internal Memory Map Functions 10debd1f3cSChristophe Leroy */ 11debd1f3cSChristophe Leroy 12debd1f3cSChristophe Leroy #include <common.h> 13debd1f3cSChristophe Leroy #include <command.h> 14debd1f3cSChristophe Leroy 15debd1f3cSChristophe Leroy #include <asm/8xx_immap.h> 16debd1f3cSChristophe Leroy #include <commproc.h> 17debd1f3cSChristophe Leroy #include <asm/iopin_8xx.h> 18ba3da734SChristophe Leroy #include <asm/io.h> 19debd1f3cSChristophe Leroy 20debd1f3cSChristophe Leroy DECLARE_GLOBAL_DATA_PTR; 21debd1f3cSChristophe Leroy 22*08dd988bSChristophe Leroy static int do_siuinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 23debd1f3cSChristophe Leroy { 24ba3da734SChristophe Leroy immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR; 25ba3da734SChristophe Leroy sysconf8xx_t __iomem *sc = &immap->im_siu_conf; 26debd1f3cSChristophe Leroy 27ba3da734SChristophe Leroy printf("SIUMCR= %08x SYPCR = %08x\n", 28ba3da734SChristophe Leroy in_be32(&sc->sc_siumcr), in_be32(&sc->sc_sypcr)); 29ba3da734SChristophe Leroy printf("SWT = %08x\n", in_be32(&sc->sc_swt)); 30ba3da734SChristophe Leroy printf("SIPEND= %08x SIMASK= %08x\n", 31ba3da734SChristophe Leroy in_be32(&sc->sc_sipend), in_be32(&sc->sc_simask)); 32ba3da734SChristophe Leroy printf("SIEL = %08x SIVEC = %08x\n", 33ba3da734SChristophe Leroy in_be32(&sc->sc_siel), in_be32(&sc->sc_sivec)); 34ba3da734SChristophe Leroy printf("TESR = %08x SDCR = %08x\n", 35ba3da734SChristophe Leroy in_be32(&sc->sc_tesr), in_be32(&sc->sc_sdcr)); 36debd1f3cSChristophe Leroy return 0; 37debd1f3cSChristophe Leroy } 38debd1f3cSChristophe Leroy 39*08dd988bSChristophe Leroy static int do_memcinfo(cmd_tbl_t *cmdtp, int flag, int argc, 40*08dd988bSChristophe Leroy char * const argv[]) 41debd1f3cSChristophe Leroy { 42ba3da734SChristophe Leroy immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR; 43ba3da734SChristophe Leroy memctl8xx_t __iomem *memctl = &immap->im_memctl; 44debd1f3cSChristophe Leroy int nbanks = 8; 45ba3da734SChristophe Leroy uint __iomem *p = &memctl->memc_br0; 46debd1f3cSChristophe Leroy int i; 47debd1f3cSChristophe Leroy 48ba3da734SChristophe Leroy for (i = 0; i < nbanks; i++, p += 2) 49ba3da734SChristophe Leroy printf("BR%-2d = %08x OR%-2d = %08x\n", 50ba3da734SChristophe Leroy i, in_be32(p), i, in_be32(p + 1)); 51debd1f3cSChristophe Leroy 52ba3da734SChristophe Leroy printf("MAR = %08x", in_be32(&memctl->memc_mar)); 53ba3da734SChristophe Leroy printf(" MCR = %08x\n", in_be32(&memctl->memc_mcr)); 54debd1f3cSChristophe Leroy printf("MAMR = %08x MBMR = %08x", 55ba3da734SChristophe Leroy in_be32(&memctl->memc_mamr), in_be32(&memctl->memc_mbmr)); 56ba3da734SChristophe Leroy printf("\nMSTAT = %04x\n", in_be16(&memctl->memc_mstat)); 57debd1f3cSChristophe Leroy printf("MPTPR = %04x MDR = %08x\n", 58ba3da734SChristophe Leroy in_be16(&memctl->memc_mptpr), in_be32(&memctl->memc_mdr)); 59debd1f3cSChristophe Leroy return 0; 60debd1f3cSChristophe Leroy } 61debd1f3cSChristophe Leroy 62*08dd988bSChristophe Leroy static int do_carinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 63debd1f3cSChristophe Leroy { 64ba3da734SChristophe Leroy immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR; 65ba3da734SChristophe Leroy car8xx_t __iomem *car = &immap->im_clkrst; 66debd1f3cSChristophe Leroy 67ba3da734SChristophe Leroy printf("SCCR = %08x\n", in_be32(&car->car_sccr)); 68ba3da734SChristophe Leroy printf("PLPRCR= %08x\n", in_be32(&car->car_plprcr)); 69ba3da734SChristophe Leroy printf("RSR = %08x\n", in_be32(&car->car_rsr)); 70debd1f3cSChristophe Leroy return 0; 71debd1f3cSChristophe Leroy } 72debd1f3cSChristophe Leroy 73debd1f3cSChristophe Leroy static int counter; 74debd1f3cSChristophe Leroy 7570fd0710SChristophe Leroy static void header(void) 76debd1f3cSChristophe Leroy { 77debd1f3cSChristophe Leroy char *data = "\ 78debd1f3cSChristophe Leroy -------------------------------- --------------------------------\ 79debd1f3cSChristophe Leroy 00000000001111111111222222222233 00000000001111111111222222222233\ 80debd1f3cSChristophe Leroy 01234567890123456789012345678901 01234567890123456789012345678901\ 81debd1f3cSChristophe Leroy -------------------------------- --------------------------------\ 82debd1f3cSChristophe Leroy "; 83debd1f3cSChristophe Leroy int i; 84debd1f3cSChristophe Leroy 85debd1f3cSChristophe Leroy if (counter % 2) 86debd1f3cSChristophe Leroy putc('\n'); 87debd1f3cSChristophe Leroy counter = 0; 88debd1f3cSChristophe Leroy 89debd1f3cSChristophe Leroy for (i = 0; i < 4; i++, data += 79) 90debd1f3cSChristophe Leroy printf("%.79s\n", data); 91debd1f3cSChristophe Leroy } 92debd1f3cSChristophe Leroy 93debd1f3cSChristophe Leroy static void binary(char *label, uint value, int nbits) 94debd1f3cSChristophe Leroy { 95debd1f3cSChristophe Leroy uint mask = 1 << (nbits - 1); 96debd1f3cSChristophe Leroy int i, second = (counter++ % 2); 97debd1f3cSChristophe Leroy 98debd1f3cSChristophe Leroy if (second) 99debd1f3cSChristophe Leroy putc(' '); 100debd1f3cSChristophe Leroy puts(label); 101debd1f3cSChristophe Leroy for (i = 32 + 1; i != nbits; i--) 102debd1f3cSChristophe Leroy putc(' '); 103debd1f3cSChristophe Leroy 104debd1f3cSChristophe Leroy while (mask != 0) { 105debd1f3cSChristophe Leroy if (value & mask) 106debd1f3cSChristophe Leroy putc('1'); 107debd1f3cSChristophe Leroy else 108debd1f3cSChristophe Leroy putc('0'); 109debd1f3cSChristophe Leroy mask >>= 1; 110debd1f3cSChristophe Leroy } 111debd1f3cSChristophe Leroy 112debd1f3cSChristophe Leroy if (second) 113debd1f3cSChristophe Leroy putc('\n'); 114debd1f3cSChristophe Leroy } 115debd1f3cSChristophe Leroy 116debd1f3cSChristophe Leroy #define PA_NBITS 16 117debd1f3cSChristophe Leroy #define PA_NB_ODR 8 118debd1f3cSChristophe Leroy #define PB_NBITS 18 119debd1f3cSChristophe Leroy #define PB_NB_ODR 16 120debd1f3cSChristophe Leroy #define PC_NBITS 12 121debd1f3cSChristophe Leroy #define PD_NBITS 13 122debd1f3cSChristophe Leroy 123*08dd988bSChristophe Leroy static int do_iopinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 124debd1f3cSChristophe Leroy { 125ba3da734SChristophe Leroy immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR; 126ba3da734SChristophe Leroy iop8xx_t __iomem *iop = &immap->im_ioport; 127ba3da734SChristophe Leroy ushort __iomem *l, *r; 128ba3da734SChristophe Leroy uint __iomem *R; 129debd1f3cSChristophe Leroy 130debd1f3cSChristophe Leroy counter = 0; 131debd1f3cSChristophe Leroy header(); 132debd1f3cSChristophe Leroy 133debd1f3cSChristophe Leroy /* 134debd1f3cSChristophe Leroy * Ports A & B 135debd1f3cSChristophe Leroy */ 136debd1f3cSChristophe Leroy 137debd1f3cSChristophe Leroy l = &iop->iop_padir; 138debd1f3cSChristophe Leroy R = &immap->im_cpm.cp_pbdir; 139ba3da734SChristophe Leroy binary("PA_DIR", in_be16(l++), PA_NBITS); 140ba3da734SChristophe Leroy binary("PB_DIR", in_be32(R++), PB_NBITS); 141ba3da734SChristophe Leroy binary("PA_PAR", in_be16(l++), PA_NBITS); 142ba3da734SChristophe Leroy binary("PB_PAR", in_be32(R++), PB_NBITS); 143ba3da734SChristophe Leroy binary("PA_ODR", in_be16(l++), PA_NB_ODR); 144ba3da734SChristophe Leroy binary("PB_ODR", in_be32(R++), PB_NB_ODR); 145ba3da734SChristophe Leroy binary("PA_DAT", in_be16(l++), PA_NBITS); 146ba3da734SChristophe Leroy binary("PB_DAT", in_be32(R++), PB_NBITS); 147debd1f3cSChristophe Leroy 148debd1f3cSChristophe Leroy header(); 149debd1f3cSChristophe Leroy 150debd1f3cSChristophe Leroy /* 151debd1f3cSChristophe Leroy * Ports C & D 152debd1f3cSChristophe Leroy */ 153debd1f3cSChristophe Leroy 154debd1f3cSChristophe Leroy l = &iop->iop_pcdir; 155debd1f3cSChristophe Leroy r = &iop->iop_pddir; 156ba3da734SChristophe Leroy binary("PC_DIR", in_be16(l++), PC_NBITS); 157ba3da734SChristophe Leroy binary("PD_DIR", in_be16(r++), PD_NBITS); 158ba3da734SChristophe Leroy binary("PC_PAR", in_be16(l++), PC_NBITS); 159ba3da734SChristophe Leroy binary("PD_PAR", in_be16(r++), PD_NBITS); 160ba3da734SChristophe Leroy binary("PC_SO ", in_be16(l++), PC_NBITS); 161debd1f3cSChristophe Leroy binary(" ", 0, 0); 162debd1f3cSChristophe Leroy r++; 163ba3da734SChristophe Leroy binary("PC_DAT", in_be16(l++), PC_NBITS); 164ba3da734SChristophe Leroy binary("PD_DAT", in_be16(r++), PD_NBITS); 165ba3da734SChristophe Leroy binary("PC_INT", in_be16(l++), PC_NBITS); 166debd1f3cSChristophe Leroy 167debd1f3cSChristophe Leroy header(); 168debd1f3cSChristophe Leroy return 0; 169debd1f3cSChristophe Leroy } 170debd1f3cSChristophe Leroy 171debd1f3cSChristophe Leroy /* 172debd1f3cSChristophe Leroy * set the io pins 173debd1f3cSChristophe Leroy * this needs a clean up for smaller tighter code 174debd1f3cSChristophe Leroy * use *uint and set the address based on cmd + port 175debd1f3cSChristophe Leroy */ 176*08dd988bSChristophe Leroy static int do_iopset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 177debd1f3cSChristophe Leroy { 178debd1f3cSChristophe Leroy uint rcode = 0; 179debd1f3cSChristophe Leroy iopin_t iopin; 18070fd0710SChristophe Leroy static uint port; 18170fd0710SChristophe Leroy static uint pin; 18270fd0710SChristophe Leroy static uint value; 183debd1f3cSChristophe Leroy static enum { 184debd1f3cSChristophe Leroy DIR, 185debd1f3cSChristophe Leroy PAR, 186debd1f3cSChristophe Leroy SOR, 187debd1f3cSChristophe Leroy ODR, 188debd1f3cSChristophe Leroy DAT, 189debd1f3cSChristophe Leroy INT 190debd1f3cSChristophe Leroy } cmd = DAT; 191debd1f3cSChristophe Leroy 192debd1f3cSChristophe Leroy if (argc != 5) { 193debd1f3cSChristophe Leroy puts("iopset PORT PIN CMD VALUE\n"); 194debd1f3cSChristophe Leroy return 1; 195debd1f3cSChristophe Leroy } 196debd1f3cSChristophe Leroy port = argv[1][0] - 'A'; 197debd1f3cSChristophe Leroy if (port > 3) 198debd1f3cSChristophe Leroy port -= 0x20; 199debd1f3cSChristophe Leroy if (port > 3) 200debd1f3cSChristophe Leroy rcode = 1; 201debd1f3cSChristophe Leroy pin = simple_strtol(argv[2], NULL, 10); 202debd1f3cSChristophe Leroy if (pin > 31) 203debd1f3cSChristophe Leroy rcode = 1; 204debd1f3cSChristophe Leroy 205debd1f3cSChristophe Leroy 206debd1f3cSChristophe Leroy switch (argv[3][0]) { 207debd1f3cSChristophe Leroy case 'd': 208debd1f3cSChristophe Leroy if (argv[3][1] == 'a') 209debd1f3cSChristophe Leroy cmd = DAT; 210debd1f3cSChristophe Leroy else if (argv[3][1] == 'i') 211debd1f3cSChristophe Leroy cmd = DIR; 212debd1f3cSChristophe Leroy else 213debd1f3cSChristophe Leroy rcode = 1; 214debd1f3cSChristophe Leroy break; 215debd1f3cSChristophe Leroy case 'p': 216debd1f3cSChristophe Leroy cmd = PAR; 217debd1f3cSChristophe Leroy break; 218debd1f3cSChristophe Leroy case 'o': 219debd1f3cSChristophe Leroy cmd = ODR; 220debd1f3cSChristophe Leroy break; 221debd1f3cSChristophe Leroy case 's': 222debd1f3cSChristophe Leroy cmd = SOR; 223debd1f3cSChristophe Leroy break; 224debd1f3cSChristophe Leroy case 'i': 225debd1f3cSChristophe Leroy cmd = INT; 226debd1f3cSChristophe Leroy break; 227debd1f3cSChristophe Leroy default: 228debd1f3cSChristophe Leroy printf("iopset: unknown command %s\n", argv[3]); 229debd1f3cSChristophe Leroy rcode = 1; 230debd1f3cSChristophe Leroy } 231debd1f3cSChristophe Leroy if (argv[4][0] == '1') 232debd1f3cSChristophe Leroy value = 1; 233debd1f3cSChristophe Leroy else if (argv[4][0] == '0') 234debd1f3cSChristophe Leroy value = 0; 235debd1f3cSChristophe Leroy else 236debd1f3cSChristophe Leroy rcode = 1; 237debd1f3cSChristophe Leroy if (rcode == 0) { 238debd1f3cSChristophe Leroy iopin.port = port; 239debd1f3cSChristophe Leroy iopin.pin = pin; 240debd1f3cSChristophe Leroy iopin.flag = 0; 241debd1f3cSChristophe Leroy switch (cmd) { 242debd1f3cSChristophe Leroy case DIR: 243debd1f3cSChristophe Leroy if (value) 244debd1f3cSChristophe Leroy iopin_set_out(&iopin); 245debd1f3cSChristophe Leroy else 246debd1f3cSChristophe Leroy iopin_set_in(&iopin); 247debd1f3cSChristophe Leroy break; 248debd1f3cSChristophe Leroy case PAR: 249debd1f3cSChristophe Leroy if (value) 250debd1f3cSChristophe Leroy iopin_set_ded(&iopin); 251debd1f3cSChristophe Leroy else 252debd1f3cSChristophe Leroy iopin_set_gen(&iopin); 253debd1f3cSChristophe Leroy break; 254debd1f3cSChristophe Leroy case SOR: 255debd1f3cSChristophe Leroy if (value) 256debd1f3cSChristophe Leroy iopin_set_opt2(&iopin); 257debd1f3cSChristophe Leroy else 258debd1f3cSChristophe Leroy iopin_set_opt1(&iopin); 259debd1f3cSChristophe Leroy break; 260debd1f3cSChristophe Leroy case ODR: 261debd1f3cSChristophe Leroy if (value) 262debd1f3cSChristophe Leroy iopin_set_odr(&iopin); 263debd1f3cSChristophe Leroy else 264debd1f3cSChristophe Leroy iopin_set_act(&iopin); 265debd1f3cSChristophe Leroy break; 266debd1f3cSChristophe Leroy case DAT: 267debd1f3cSChristophe Leroy if (value) 268debd1f3cSChristophe Leroy iopin_set_high(&iopin); 269debd1f3cSChristophe Leroy else 270debd1f3cSChristophe Leroy iopin_set_low(&iopin); 271debd1f3cSChristophe Leroy break; 272debd1f3cSChristophe Leroy case INT: 273debd1f3cSChristophe Leroy if (value) 274debd1f3cSChristophe Leroy iopin_set_falledge(&iopin); 275debd1f3cSChristophe Leroy else 276debd1f3cSChristophe Leroy iopin_set_anyedge(&iopin); 277debd1f3cSChristophe Leroy break; 278debd1f3cSChristophe Leroy } 279debd1f3cSChristophe Leroy } 280debd1f3cSChristophe Leroy return rcode; 281debd1f3cSChristophe Leroy } 282debd1f3cSChristophe Leroy 283debd1f3cSChristophe Leroy static void prbrg(int n, uint val) 284debd1f3cSChristophe Leroy { 285debd1f3cSChristophe Leroy uint extc = (val >> 14) & 3; 286debd1f3cSChristophe Leroy uint cd = (val & CPM_BRG_CD_MASK) >> 1; 287debd1f3cSChristophe Leroy uint div16 = (val & CPM_BRG_DIV16) != 0; 288debd1f3cSChristophe Leroy 289debd1f3cSChristophe Leroy ulong clock = gd->cpu_clk; 290debd1f3cSChristophe Leroy 291debd1f3cSChristophe Leroy printf("BRG%d:", n); 292debd1f3cSChristophe Leroy 293debd1f3cSChristophe Leroy if (val & CPM_BRG_RST) 294debd1f3cSChristophe Leroy puts(" RESET"); 295debd1f3cSChristophe Leroy else 296debd1f3cSChristophe Leroy puts(" "); 297debd1f3cSChristophe Leroy 298debd1f3cSChristophe Leroy if (val & CPM_BRG_EN) 299debd1f3cSChristophe Leroy puts(" ENABLED"); 300debd1f3cSChristophe Leroy else 301debd1f3cSChristophe Leroy puts(" DISABLED"); 302debd1f3cSChristophe Leroy 303debd1f3cSChristophe Leroy printf(" EXTC=%d", extc); 304debd1f3cSChristophe Leroy 305debd1f3cSChristophe Leroy if (val & CPM_BRG_ATB) 306debd1f3cSChristophe Leroy puts(" ATB"); 307debd1f3cSChristophe Leroy else 308debd1f3cSChristophe Leroy puts(" "); 309debd1f3cSChristophe Leroy 310debd1f3cSChristophe Leroy printf(" DIVIDER=%4d", cd); 311debd1f3cSChristophe Leroy if (extc == 0 && cd != 0) { 312debd1f3cSChristophe Leroy uint baudrate; 313debd1f3cSChristophe Leroy 314debd1f3cSChristophe Leroy if (div16) 315debd1f3cSChristophe Leroy baudrate = (clock / 16) / (cd + 1); 316debd1f3cSChristophe Leroy else 317debd1f3cSChristophe Leroy baudrate = clock / (cd + 1); 318debd1f3cSChristophe Leroy 319debd1f3cSChristophe Leroy printf("=%6d bps", baudrate); 320debd1f3cSChristophe Leroy } else { 321debd1f3cSChristophe Leroy puts(" "); 322debd1f3cSChristophe Leroy } 323debd1f3cSChristophe Leroy 324debd1f3cSChristophe Leroy if (val & CPM_BRG_DIV16) 325debd1f3cSChristophe Leroy puts(" DIV16"); 326debd1f3cSChristophe Leroy else 327debd1f3cSChristophe Leroy puts(" "); 328debd1f3cSChristophe Leroy 329debd1f3cSChristophe Leroy putc('\n'); 330debd1f3cSChristophe Leroy } 331debd1f3cSChristophe Leroy 332*08dd988bSChristophe Leroy static int do_brginfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 333debd1f3cSChristophe Leroy { 334ba3da734SChristophe Leroy immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR; 335ba3da734SChristophe Leroy cpm8xx_t __iomem *cp = &immap->im_cpm; 336ba3da734SChristophe Leroy uint __iomem *p = &cp->cp_brgc1; 337debd1f3cSChristophe Leroy int i = 1; 338debd1f3cSChristophe Leroy 339debd1f3cSChristophe Leroy while (i <= 4) 340ba3da734SChristophe Leroy prbrg(i++, in_be32(p++)); 341debd1f3cSChristophe Leroy 342debd1f3cSChristophe Leroy return 0; 343debd1f3cSChristophe Leroy } 344debd1f3cSChristophe Leroy 345debd1f3cSChristophe Leroy /***************************************************/ 346debd1f3cSChristophe Leroy 347debd1f3cSChristophe Leroy U_BOOT_CMD( 348debd1f3cSChristophe Leroy siuinfo, 1, 1, do_siuinfo, 349debd1f3cSChristophe Leroy "print System Interface Unit (SIU) registers", 350debd1f3cSChristophe Leroy "" 351debd1f3cSChristophe Leroy ); 352debd1f3cSChristophe Leroy 353debd1f3cSChristophe Leroy U_BOOT_CMD( 354debd1f3cSChristophe Leroy memcinfo, 1, 1, do_memcinfo, 355debd1f3cSChristophe Leroy "print Memory Controller registers", 356debd1f3cSChristophe Leroy "" 357debd1f3cSChristophe Leroy ); 358debd1f3cSChristophe Leroy 359debd1f3cSChristophe Leroy U_BOOT_CMD( 360debd1f3cSChristophe Leroy carinfo, 1, 1, do_carinfo, 361debd1f3cSChristophe Leroy "print Clocks and Reset registers", 362debd1f3cSChristophe Leroy "" 363debd1f3cSChristophe Leroy ); 364debd1f3cSChristophe Leroy 365debd1f3cSChristophe Leroy U_BOOT_CMD( 366debd1f3cSChristophe Leroy iopinfo, 1, 1, do_iopinfo, 367debd1f3cSChristophe Leroy "print I/O Port registers", 368debd1f3cSChristophe Leroy "" 369debd1f3cSChristophe Leroy ); 370debd1f3cSChristophe Leroy 371debd1f3cSChristophe Leroy U_BOOT_CMD( 372debd1f3cSChristophe Leroy iopset, 5, 0, do_iopset, 373debd1f3cSChristophe Leroy "set I/O Port registers", 374debd1f3cSChristophe Leroy "PORT PIN CMD VALUE\nPORT: A-D, PIN: 0-31, CMD: [dat|dir|odr|sor], VALUE: 0|1" 375debd1f3cSChristophe Leroy ); 376debd1f3cSChristophe Leroy 377debd1f3cSChristophe Leroy U_BOOT_CMD( 378debd1f3cSChristophe Leroy brginfo, 1, 1, do_brginfo, 379debd1f3cSChristophe Leroy "print Baud Rate Generator (BRG) registers", 380debd1f3cSChristophe Leroy "" 381debd1f3cSChristophe Leroy ); 382