1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * LAUSANNE-specific commands File: ui_lausanne.c 5 * 6 * A temporary sandbox for misc test routines and commands. 7 * 8 * Author: Mitch Lichtenberg 9 * 10 ********************************************************************* 11 * 12 * Copyright 2000,2001,2002,2003,2004 13 * Broadcom Corporation. All rights reserved. 14 * 15 * This software is furnished under license and may be used and 16 * copied only in accordance with the following terms and 17 * conditions. Subject to these conditions, you may download, 18 * copy, install, use, modify and distribute modified or unmodified 19 * copies of this software in source and/or binary form. No title 20 * or ownership is transferred hereby. 21 * 22 * 1) Any source code used, modified or distributed must reproduce 23 * and retain this copyright notice and list of conditions 24 * as they appear in the source file. 25 * 26 * 2) No right is granted to use any trade name, trademark, or 27 * logo of Broadcom Corporation. The "Broadcom Corporation" 28 * name may not be used to endorse or promote products derived 29 * from this software without the prior written permission of 30 * Broadcom Corporation. 31 * 32 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 33 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 34 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 35 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 36 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 37 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 38 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 39 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 40 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 41 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 42 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 43 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 44 * THE POSSIBILITY OF SUCH DAMAGE. 45 ********************************************************************* */ 46 47 48#include "cfe.h" 49#include "ui_command.h" 50#if CFG_PCI 51#include "pcivar.h" 52#endif 53 54#include "sbmips.h" 55#include "sb1250_regs.h" 56#include "sb1250_genbus.h" 57#include "lausanne.h" 58 59 60/* ********************************************************************* 61 * Configuration 62 ********************************************************************* */ 63 64#ifndef DEBUG_CS 65#define DEBUG_CS 0 66#endif 67 68 69/* ********************************************************************* 70 * prototypes 71 ********************************************************************* */ 72 73int ui_init_swarmcmds(void); 74 75int ui_init_cpldcmds(void); 76static int ui_cmd_writecpld(ui_cmdline_t *cmd,int argc,char *argv[]); 77static int ui_cmd_readcpld(ui_cmdline_t *cmd,int argc,char *argv[]); 78static int ui_cmd_burstwcpld(ui_cmdline_t *cmd,int argc,char *argv[]); 79static int ui_cmd_burstrcpld(ui_cmdline_t *cmd,int argc,char *argv[]); 80static int ui_cmd_config_flash(ui_cmdline_t *cmd,int argc,char *argv[]); 81 82#if CFG_PCI 83static int ui_cmd_map_pci(ui_cmdline_t *cmd,int argc,char *argv[]); 84#endif 85 86#if CFG_VGACONSOLE 87static int ui_cmd_vgadump(ui_cmdline_t *cmd,int argc,char *argv[]); 88static int ui_cmd_vgainit(ui_cmdline_t *cmd,int argc,char *argv[]); 89extern int vga_biosinit(void); 90extern void vgaraw_dump(char *tail); 91#endif 92 93static int burst_mode(unsigned int cs, int burst_on); 94static int intel_flash_data_width_mode(unsigned int cs, int flash_16bit); 95 96 97/* ********************************************************************* 98 * Data 99 ********************************************************************* */ 100 101 102/* ********************************************************************* 103 * ui_init_swarmcmds() 104 * 105 * Add SWARM-specific commands to the command table 106 * 107 * Input parameters: 108 * nothing 109 * 110 * Return value: 111 * 0 112 ********************************************************************* */ 113 114 115int ui_init_swarmcmds(void) 116{ 117#if CFG_PCI 118 cmd_addcmd("map pci", 119 ui_cmd_map_pci, 120 NULL, 121 "Define a BAR0 window available to PCI devices", 122 "map pci offset size paddr [-off] [-l2ca] [-matchbits]\n\n" 123 "Map the region of size bytes starting at paddr to appear\n" 124 "at offset relative to BAR0\n", 125 "-off;Remove the region|" 126 "-l2ca;Make L2 cachable|" 127 "-matchbits;Use match bits policy"); 128#endif 129#if CFG_VGACONSOLE 130 cmd_addcmd("vga init", 131 ui_cmd_vgainit, 132 NULL, 133 "Initialize the VGA adapter.", 134 "vgainit", 135 ""); 136 137 cmd_addcmd("vga dumpbios", 138 ui_cmd_vgadump, 139 NULL, 140 "Dump the VGA BIOS to the console", 141 "vga dumpbios", 142 ""); 143#endif 144 145 146 return 0; 147} 148 149 150#if CFG_PCI 151static uint64_t parse_hex(const char *num) 152{ 153 uint64_t x = 0; 154 unsigned int digit; 155 156 if ((*num == '0') && (*(num+1) == 'x')) num += 2; 157 158 while (*num) { 159 if ((*num >= '0') && (*num <= '9')) { 160 digit = *num - '0'; 161 } 162 else if ((*num >= 'A') && (*num <= 'F')) { 163 digit = 10 + *num - 'A'; 164 } 165 else if ((*num >= 'a') && (*num <= 'f')) { 166 digit = 10 + *num - 'a'; 167 } 168 else { 169 break; 170 } 171 x *= 16; 172 x += digit; 173 num++; 174 } 175 176 return x; 177} 178 179static int ui_cmd_map_pci(ui_cmdline_t *cmd,int argc,char *argv[]) 180{ 181 unsigned long offset, size; 182 uint64_t paddr; 183 int l2ca, endian; 184 int enable; 185 int result; 186 187 enable = !cmd_sw_isset(cmd, "-off"); 188 if (enable) { 189 offset = parse_hex(cmd_getarg(cmd, 0)); 190 size = parse_hex(cmd_getarg(cmd, 1)); 191 paddr = parse_hex(cmd_getarg(cmd, 2)); 192 l2ca = cmd_sw_isset(cmd,"-l2ca"); 193 endian = cmd_sw_isset(cmd, "-matchbits"); 194 result = pci_map_window(paddr, offset, size, l2ca, endian); 195 } 196 else { 197 offset = parse_hex(cmd_getarg(cmd, 0)); 198 size = parse_hex(cmd_getarg(cmd, 1)); 199 result = pci_unmap_window(offset, size); 200 } 201 202 return result; 203} 204#endif 205 206 207#if CFG_VGACONSOLE 208static int ui_cmd_vgainit(ui_cmdline_t *cmd,int argc,char *argv[]) 209{ 210 int res; 211 212 res = vga_biosinit(); 213 214 xprintf("vgaraw_init returns %d\n",res); 215 216 return 0; 217} 218 219static int ui_cmd_vgadump(ui_cmdline_t *cmd,int argc,char *argv[]) 220{ 221 char *x; 222 223 x = cmd_getarg(cmd,0); 224 if (!x) x = ""; 225 226 vgaraw_dump(x); 227 228 return 0; 229} 230#endif 231 232 233int ui_init_cpldcmds(void) 234{ 235 236 cmd_addcmd("write cpld", 237 ui_cmd_writecpld, 238 NULL, 239 "Write bytes to the cpld", 240 "write cpld", 241 ""); 242 243 cmd_addcmd("read cpld", 244 ui_cmd_readcpld, 245 NULL, 246 "Read bytes from the cpld", 247 "read cpld", 248 ""); 249 250 cmd_addcmd("burstw cpld", 251 ui_cmd_burstwcpld, 252 NULL, 253 "Write to the cpld in 8-bit BURST MODE", 254 "burstw cpld", 255 ""); 256 257 cmd_addcmd("burstr cpld", 258 ui_cmd_burstrcpld, 259 NULL, 260 "Read from the cpld in 8-bit BURST MODE", 261 "burstr cpld", 262 ""); 263 264 cmd_addcmd("config flash", 265 ui_cmd_config_flash, 266 NULL, 267 "Configure width and burst mode for the Intel flash.", 268 "config flash [-n|-w] [-b|-o]", 269 "-n;switch flash1 to 8-bit mode|" 270 "-w;switch flash1 to 16-bit mode|" 271 "-b;burst on|" 272 "-o;burst off"); 273 return 0; 274} 275 276 277/* NORMAL WRITE to the cpld 278 * Write 8'b01010101 to address 8'b00000001 of the cpld 279 */ 280static int ui_cmd_writecpld(ui_cmdline_t *cmd,int argc,char *argv[]) 281{ 282 /* Make sure burst mode is DISABLED. */ 283 burst_mode(CPLD_CS, 0); 284 285 xprintf ("writing 0x55 to cpld address 0x01\n"); 286 *((volatile uint8_t *) PHYS_TO_K1(CPLD_PHYS+0x01)) = (uint8_t) (0x55); 287 return 0; 288} 289 290 291/* NORMAL READ to the cpld 292 * The cpld is programmed to output the current cpld SUM if address 0x00 is 293 * read. However, if any other address is read, then the cpld will output 294 * 5'b00000 concatenated with the lowest three address bits. 295 * ie. 296 * reading address 0xFF will return 0x07. 297 * reading address 0x4A will return 0x02. 298 * reading address 0x09 will return 0x01. 299 */ 300static int ui_cmd_readcpld(ui_cmdline_t *cmd,int argc,char *argv[]) 301{ 302 uint8_t data; 303 304 /* make sure burst mode is DISABLED. */ 305 burst_mode(CPLD_CS, 0); 306 307 data = *((volatile uint8_t *) PHYS_TO_K1(CPLD_PHYS+0xFC)); 308 xprintf ("CPLD address 0xFC contains 0x%2X\n", data); 309 xprintf ("This value should be 0x04\n"); 310 data = *((volatile uint8_t *) PHYS_TO_K1(CPLD_PHYS)); 311 xprintf ("CPLD address 0x00 contains 0x%2X\n", data); 312 313 return 0; 314} 315 316 317/* BURST WRITE to the cpld 318 * Maximum burst size (without doing a UAC store) to cpld is 8 bytes. 319 * byte1: 0x01 320 * byte2: 0x02 321 * byte3: 0x04 322 * byte4: 0x08 323 * byte5: 0x10 324 * byte6: 0x20 325 * byte7: 0x40 326 * byte8: 0x80 327 * To do the burst, write the 64-bit value 0x8040201008040201 to the cpld. 328 * At the end of the burst, the cpld SUM register should contain 0xFF. 329 */ 330static int ui_cmd_burstwcpld(ui_cmdline_t *cmd,int argc,char *argv[]) 331{ 332 /* Enable burst mode. */ 333 burst_mode(CPLD_CS, 1); 334 335 xprintf("burst writing 8 bytes (0x8040201008040201) to cpld address 0x00\n"); 336 *((volatile uint64_t *) PHYS_TO_K1(CPLD_PHYS)) = (uint64_t) (0x8040201008040201ULL); 337 338 return 0; 339} 340 341 342/* BURST READ to the cpld 343 * Burst reading the cpld at address 0x00 should return 344 * 0x07060504030201 concatenated with the cpld SUM[7:0] 345 */ 346static int ui_cmd_burstrcpld(ui_cmdline_t *cmd,int argc,char *argv[]) 347{ 348 uint64_t data; 349 350 /* Enable burst mode */ 351 burst_mode(CPLD_CS, 1); 352 353 data = *((volatile uint64_t *) PHYS_TO_K1(CPLD_PHYS)); 354 xprintf ("Address 0x00 of cpld contains (by burst reading) 0x%16X\n", data); 355 xprintf ("This value should be 0x07060504030201FF if a burst write was just executed\n"); 356 357 return 0; 358} 359 360static int ui_cmd_config_flash(ui_cmdline_t *cmd,int argc,char *argv[]) 361{ 362 uint64_t gpio_data; 363 unsigned int cs; 364 int flash_16bit = 0; 365 int burst_on = 0; 366 367 /* Burst and 16-bit modes make sense only for the Intel flash; the 368 alternative "flash" is a PromICE connector. Do not change mode 369 while running from that flash, and do not attempt to update the 370 flash except in 8-bit, non-burst mode (the default). */ 371 372 /* Boot flash selection is at pin 9 on GPIO; refer to lausanne.h */ 373 gpio_data = SBREADCSR(A_GPIO_READ); 374 cs = (gpio_data & _SB_MAKEMASK1(GPIO_BOOT_SELECT)) ? 375 BOOTROM_CS : ALT_BOOTROM_CS; 376 377 if (cmd_sw_isset(cmd,"-w")) { 378 /*switch to 16-bit mode*/ 379 flash_16bit = 1; 380 } 381 else if (cmd_sw_isset(cmd,"-n")) { 382 /*switch to 8-bit mode*/ 383 flash_16bit = 0; 384 } 385 intel_flash_data_width_mode(cs, flash_16bit); 386 387 if (cmd_sw_isset(cmd,"-b")) { 388 burst_on = 1; 389 } 390 else if (cmd_sw_isset(cmd,"-o")) { 391 burst_on = 0; 392 } 393 burst_mode(cs, burst_on); 394 395 return 0; 396 397} 398 399 400/* ********************************************************************* 401 * Utilities 402 ********************************************************************* */ 403 404static int intel_flash_data_width_mode(unsigned int cs, int flash_16bit) 405{ 406 uint64_t gpio_direction; 407 uint64_t io_ext_cfg; 408 409 gpio_direction = SBREADCSR(A_GPIO_DIRECTION); 410 411 io_ext_cfg = SBREADCSR(A_IO_EXT_CS_BASE(cs)); 412 io_ext_cfg &= ~M_IO_WIDTH_SEL; 413 414 if (flash_16bit) { 415 gpio_direction |= _SB_MAKEMASK1(GPIO_FLASH_BYTE_EN); 416 SBWRITECSR(A_GPIO_DIRECTION,gpio_direction); 417 418 if (DEBUG_CS) xprintf("FLASH CS %d: 16-BIT MODE\n", cs); 419 SBWRITECSR(A_GPIO_PIN_SET,_SB_MAKEMASK1(GPIO_FLASH_BYTE_EN)); 420 421 /* GENBUS CS: mux'ed and 2 bytes wide */ 422 io_ext_cfg |= V_IO_WIDTH_SEL(K_IO_WIDTH_SEL_2); 423 io_ext_cfg &= ~M_IO_NONMUX; /* make sure we're mux'ed!! */ 424 SBWRITECSR(A_IO_EXT_CS_BASE(cs),io_ext_cfg); 425 } 426 else { /* 8 bit flash */ 427 gpio_direction &= ~_SB_MAKEMASK1(GPIO_FLASH_BYTE_EN); /* XXX eh?? */ 428 SBWRITECSR(A_GPIO_DIRECTION,gpio_direction); 429 430 if (DEBUG_CS) xprintf("FLASH CS %d: 8-BIT MODE\n", cs); 431 SBWRITECSR(A_GPIO_PIN_CLR,_SB_MAKEMASK1(GPIO_FLASH_BYTE_EN)); 432 433 /* GENBUS CS: nonmux'ed and 1 byte wide */ 434 io_ext_cfg |= M_IO_NONMUX | V_IO_WIDTH_SEL(K_IO_WIDTH_SEL_1); 435 SBWRITECSR(A_IO_EXT_CS_BASE(cs),io_ext_cfg); 436 } 437 return 0; 438} 439 440static int burst_mode(unsigned int cs, int burst_on) 441{ 442 uint64_t io_ext_cfg; 443 444 /*GENBUS CS */ 445 io_ext_cfg = SBREADCSR(A_IO_EXT_CS_BASE(cs)); 446 447 if (burst_on) { 448 io_ext_cfg |= M_IO_BURST_EN; 449 SBWRITECSR(A_IO_EXT_CS_BASE(cs), io_ext_cfg); 450 if (DEBUG_CS) xprintf("FLASH CS %d: BURST ON\n",cs); 451 } 452 else { /*burst off*/ 453 io_ext_cfg &= ~M_IO_BURST_EN; 454 SBWRITECSR(A_IO_EXT_CS_BASE(cs),io_ext_cfg); 455 if (DEBUG_CS) xprintf("FLASH CS %d: BURST OFF\n",cs); 456 } 457 458 return 0; 459} 460