1 /* 2 * caddy.c -- esd VME8349 support for "missing" access modes in TSI148. 3 * Copyright (c) 2009 esd gmbh. 4 * 5 * Reinhard Arlt <reinhard.arlt@esd-electronics.com> 6 * 7 * See file CREDITS for list of people who contributed to this 8 * project. 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License as 12 * published by the Free Software Foundation; either version 2 of 13 * the License, or (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 23 * MA 02111-1307 USA 24 * 25 */ 26 27 #include <common.h> 28 #include <ioports.h> 29 #include <mpc83xx.h> 30 #include <asm/mpc8349_pci.h> 31 #include <pci.h> 32 #include <asm/mmu.h> 33 #include <asm/io.h> 34 35 #include "caddy.h" 36 37 static struct caddy_interface *caddy_interface; 38 39 void generate_answer(struct caddy_cmd *cmd, uint32_t status, uint32_t *result) 40 { 41 struct caddy_answer *answer; 42 uint32_t ptr; 43 44 answer = &caddy_interface->answer[caddy_interface->answer_in]; 45 memset((void *)answer, 0, sizeof(struct caddy_answer)); 46 answer->answer = cmd->cmd; 47 answer->issue = cmd->issue; 48 answer->status = status; 49 memcpy(answer->par, result, 5 * sizeof(result[0])); 50 ptr = caddy_interface->answer_in + 1; 51 ptr = ptr & (ANSWER_SIZE - 1); 52 if (ptr != caddy_interface->answer_out) 53 caddy_interface->answer_in = ptr; 54 } 55 56 int do_caddy(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 57 { 58 unsigned long base_addr; 59 uint32_t ptr; 60 struct caddy_cmd *caddy_cmd; 61 uint32_t result[5]; 62 uint16_t data16; 63 uint8_t data8; 64 uint32_t status; 65 pci_dev_t dev; 66 void *pci_ptr; 67 68 if (argc < 2) { 69 puts("Missing parameter\n"); 70 return 1; 71 } 72 73 base_addr = simple_strtoul(argv[1], NULL, 16); 74 caddy_interface = (struct caddy_interface *) base_addr; 75 76 memset((void *)caddy_interface, 0, sizeof(struct caddy_interface)); 77 memcpy((void *)&caddy_interface->magic[0], &CADDY_MAGIC, 16); 78 79 while (ctrlc() == 0) { 80 if (caddy_interface->cmd_in != caddy_interface->cmd_out) { 81 memset(result, 0, 5 * sizeof(result[0])); 82 status = 0; 83 caddy_cmd = &caddy_interface->cmd[caddy_interface->cmd_out]; 84 pci_ptr = (void *)CONFIG_SYS_PCI1_IO_PHYS + 85 (caddy_cmd->addr & 0x001fffff); 86 87 switch (caddy_cmd->cmd) { 88 case CADDY_CMD_IO_READ_8: 89 result[0] = in_8(pci_ptr); 90 break; 91 92 case CADDY_CMD_IO_READ_16: 93 result[0] = in_be16(pci_ptr); 94 break; 95 96 case CADDY_CMD_IO_READ_32: 97 result[0] = in_be32(pci_ptr); 98 break; 99 100 case CADDY_CMD_IO_WRITE_8: 101 data8 = caddy_cmd->par[0] & 0x000000ff; 102 out_8(pci_ptr, data8); 103 break; 104 105 case CADDY_CMD_IO_WRITE_16: 106 data16 = caddy_cmd->par[0] & 0x0000ffff; 107 out_be16(pci_ptr, data16); 108 break; 109 110 case CADDY_CMD_IO_WRITE_32: 111 out_be32(pci_ptr, caddy_cmd->par[0]); 112 break; 113 114 case CADDY_CMD_CONFIG_READ_8: 115 dev = PCI_BDF(caddy_cmd->par[0], 116 caddy_cmd->par[1], 117 caddy_cmd->par[2]); 118 status = pci_read_config_byte(dev, 119 caddy_cmd->addr, 120 &data8); 121 result[0] = data8; 122 break; 123 124 case CADDY_CMD_CONFIG_READ_16: 125 dev = PCI_BDF(caddy_cmd->par[0], 126 caddy_cmd->par[1], 127 caddy_cmd->par[2]); 128 status = pci_read_config_word(dev, 129 caddy_cmd->addr, 130 &data16); 131 result[0] = data16; 132 break; 133 134 case CADDY_CMD_CONFIG_READ_32: 135 dev = PCI_BDF(caddy_cmd->par[0], 136 caddy_cmd->par[1], 137 caddy_cmd->par[2]); 138 status = pci_read_config_dword(dev, 139 caddy_cmd->addr, 140 &result[0]); 141 break; 142 143 case CADDY_CMD_CONFIG_WRITE_8: 144 dev = PCI_BDF(caddy_cmd->par[0], 145 caddy_cmd->par[1], 146 caddy_cmd->par[2]); 147 data8 = caddy_cmd->par[3] & 0x000000ff; 148 status = pci_write_config_byte(dev, 149 caddy_cmd->addr, 150 data8); 151 break; 152 153 case CADDY_CMD_CONFIG_WRITE_16: 154 dev = PCI_BDF(caddy_cmd->par[0], 155 caddy_cmd->par[1], 156 caddy_cmd->par[2]); 157 data16 = caddy_cmd->par[3] & 0x0000ffff; 158 status = pci_write_config_word(dev, 159 caddy_cmd->addr, 160 data16); 161 break; 162 163 case CADDY_CMD_CONFIG_WRITE_32: 164 dev = PCI_BDF(caddy_cmd->par[0], 165 caddy_cmd->par[1], 166 caddy_cmd->par[2]); 167 status = pci_write_config_dword(dev, 168 caddy_cmd->addr, 169 caddy_cmd->par[3]); 170 break; 171 172 default: 173 status = 0xffffffff; 174 break; 175 } 176 177 generate_answer(caddy_cmd, status, &result[0]); 178 179 ptr = caddy_interface->cmd_out + 1; 180 ptr = ptr & (CMD_SIZE - 1); 181 caddy_interface->cmd_out = ptr; 182 } 183 184 caddy_interface->heartbeat++; 185 } 186 187 return 0; 188 } 189 190 U_BOOT_CMD( 191 caddy, 2, 0, do_caddy, 192 "Start Caddy server.", 193 "Start Caddy server with Data structure a given addr\n" 194 ); 195