/** * bus->driver->(*new_bus) * */ static urj_bus_t * prototype_bus_new (urj_chain_t *chain, const urj_bus_driver_t *driver, const urj_param_t *cmd_params[]) { urj_bus_t *bus; urj_part_signal_t *sig; char buff[16], fmt[16], afmt[16], dfmt[16]; int i, j, inst, max, min; int failed = 0; int ashift = -1; const char *value; bus = urj_bus_generic_new (chain, driver, sizeof (bus_params_t)); if (bus == NULL) return NULL; CS = OE = WE = NULL; ALSBI = AMSBI = DLSBI = DMSBI = -1; for (i = 0; cmd_params[i] != NULL; i++) { if (cmd_params[i]->key == URJ_BUS_PARAM_KEY_AMODE || cmd_params[i]->key == URJ_BUS_PARAM_KEY_WIDTH) { switch (cmd_params[i]->value.lu) { case 8: ashift = 0; break; case 16: ashift = 1; break; case 32: ashift = 2; break; case 0: // "auto" break; default: urj_error_set (URJ_ERROR_INVALID, _("value %lu not defined for parameter %s"), cmd_params[i]->value.lu, urj_param_string(&urj_bus_param_list, cmd_params[i])); failed = 1; // @@@@ RFHH break; } } else { if (cmd_params[i]->type != URJ_PARAM_TYPE_STRING) { urj_error_set (URJ_ERROR_SYNTAX, "parameter must be of type string"); failed = 1; continue; } value = cmd_params[i]->value.string; inst = 32; prototype_bus_signal_parse (value, fmt, &inst); // @@@@ RFHH Flag error? // @@@@ RFHH If it is mandatory for a signal to have an int inst // number, why does prototype_bus_signal_parse() accept values // without an int? if (inst > 31 || inst < 0) continue; sig = urj_part_find_signal (bus->part, value); if (!sig) { urj_error_set (URJ_ERROR_NOTFOUND, _("signal '%s' not found"), value); failed = 1; continue; } switch (cmd_params[i]->key) { case URJ_BUS_PARAM_KEY_ALSB: ALSBI = inst; A[inst] = sig; strcpy (afmt, fmt); break; case URJ_BUS_PARAM_KEY_AMSB: AMSBI = inst; A[inst] = sig; strcpy (afmt, fmt); break; case URJ_BUS_PARAM_KEY_DLSB: DLSBI = inst; D[inst] = sig; strcpy (dfmt, fmt); break; case URJ_BUS_PARAM_KEY_DMSB: DMSBI = inst; D[inst] = sig; strcpy (dfmt, fmt); break; case URJ_BUS_PARAM_KEY_CS: case URJ_BUS_PARAM_KEY_NCS: CS = sig; CSA = (cmd_params[i]->key == URJ_BUS_PARAM_KEY_CS); break; case URJ_BUS_PARAM_KEY_OE: case URJ_BUS_PARAM_KEY_NOE: OE = sig; OEA = (cmd_params[i]->key == URJ_BUS_PARAM_KEY_OE); break; case URJ_BUS_PARAM_KEY_WE: case URJ_BUS_PARAM_KEY_NWE: WE = sig; WEA = (cmd_params[i]->key == URJ_BUS_PARAM_KEY_WE); break; default: urj_error_set (URJ_ERROR_INVALID, _("parameter %s is unknown"), urj_param_string(&urj_bus_param_list, cmd_params[i])); failed = 1; break; } } } if (ALSBI >= 0 || AMSBI >= 0) { if (ALSBI == -1 || AMSBI == -1) { for (min = 0; min <= 31; min++) { sprintf (buff, afmt, min); A[min] = urj_part_find_signal (bus->part, buff); if (A[min]) break; } for (max = 31; max >= 0; max--) { sprintf (buff, afmt, max); A[max] = urj_part_find_signal (bus->part, buff); if (A[max]) break; } if (ALSBI == -1) ALSBI = (max - AMSBI < AMSBI - min) ? min : max; else AMSBI = (max - ALSBI < ALSBI - min) ? min : max; } AI = (AMSBI > ALSBI ? 1 : -1); AW = (AMSBI > ALSBI ? AMSBI - ALSBI : ALSBI - AMSBI) + 1; for (i = 0, j = ALSBI; i < AW; i++, j += AI) { sprintf (buff, afmt, j); // @@@@ RFHH check result A[j] = urj_part_find_signal (bus->part, buff); } } else { urj_error_set (URJ_ERROR_INVALID, _("parameters alsb=<signal> and/or amsb=<signal> are not defined")); failed = 1; } if (DLSBI >= 0 || DMSBI >= 0) { if (DLSBI == -1 || DMSBI == -1) { for (min = 0; min <= 31; min++) { sprintf (buff, dfmt, min); D[min] = urj_part_find_signal (bus->part, buff); if (D[min]) break; } for (max = 31; max >= 0; max--) { sprintf (buff, dfmt, max); D[max] = urj_part_find_signal (bus->part, buff); if (D[max]) break; } if (DLSBI == -1) DLSBI = (max - DMSBI < DMSBI - min) ? min : max; else DMSBI = (max - DLSBI < DLSBI - min) ? min : max; } DI = (DMSBI > DLSBI ? 1 : -1); DW = (DMSBI > DLSBI ? DMSBI - DLSBI : DLSBI - DMSBI) + 1; for (i = 0, j = DLSBI; i < DW; i++, j += DI) { sprintf (buff, dfmt, j); D[j] = urj_part_find_signal (bus->part, buff); } /* bus drivers are called with a byte address this address needs to be adjusted by setup_address() to the memory data width */ if (ashift < 0) { int nbytes; /* parameter 'amode' wasn't specified, derive the address shift from the data bus width */ nbytes = DW / 8; if (DW % 8 > 0) nbytes++; ashift = 0; while (nbytes != 1) { nbytes >>= 1; ashift++; } } ASHIFT = ashift; }
/** * bus->driver->(*new_bus) * */ static urj_bus_t * avr32_bus_new (urj_chain_t *chain, const urj_bus_driver_t *driver, const urj_param_t *cmd_params[]) { urj_bus_t *bus; urj_part_t *part; unsigned int mode = BUS_MODE_ERROR; if (cmd_params[0] == NULL) { urj_error_set (URJ_ERROR_SYNTAX, "no bus mode specified"); return NULL; } if (cmd_params[1] != NULL) { urj_error_set (URJ_ERROR_SYNTAX, "invalid bus parameter: %s", urj_param_string(&urj_bus_param_list, cmd_params[1])); return NULL; } bus = urj_bus_generic_new (chain, driver, sizeof (bus_params_t)); if (bus == NULL) return NULL; part = bus->part; switch (cmd_params[0]->key) { case URJ_BUS_PARAM_KEY_OCD: mode = BUS_MODE_OCD; break; case URJ_BUS_PARAM_KEY_HSBC: mode = BUS_MODE_HSBC; break; case URJ_BUS_PARAM_KEY_HSBU: mode = BUS_MODE_HSBU; break; case URJ_BUS_PARAM_KEY_X8: // see also: width=8 mode = BUS_MODE_x8; break; case URJ_BUS_PARAM_KEY_X16: // see also: width=16 mode = BUS_MODE_x16; break; case URJ_BUS_PARAM_KEY_X32: // see also: width=32 mode = BUS_MODE_x32; break; // RFHH introduced 'width=8|16|32' as an alias for x8, x16, x32 case URJ_BUS_PARAM_KEY_WIDTH: switch (cmd_params[0]->value.lu) { case 8: mode = BUS_MODE_x8; break; case 16: mode = BUS_MODE_x16; break; case 32: mode = BUS_MODE_x32; break; default: urj_bus_generic_free (bus); urj_error_set (URJ_ERROR_SYNTAX, "invalid bus width: %lu", cmd_params[0]->value.lu); return NULL; } break; default: urj_bus_generic_free (bus); urj_error_set (URJ_ERROR_SYNTAX, "invalid bus mode: %s", urj_param_string(&urj_bus_param_list, cmd_params[0])); return NULL; } switch (mode) { case BUS_MODE_OCD: case BUS_MODE_HSBC: case BUS_MODE_HSBU: if (check_instruction (part, "MEMORY_WORD_ACCESS")) { urj_bus_generic_free (bus); return NULL; } break; case BUS_MODE_x8: case BUS_MODE_x16: case BUS_MODE_x32: if (check_instruction (part, "NEXUS_ACCESS")) { urj_bus_generic_free (bus); return NULL; } break; default: urj_error_set (URJ_ERROR_INVALID, "need bus mode parameter"); urj_bus_generic_free (bus); return NULL; } avr32_bus_setup (bus, chain, part, mode); return bus; }
static urj_bus_t * mpc837x_bus_new( urj_chain_t *chain, const urj_bus_driver_t *driver, const urj_param_t *cmd_params[] ) { urj_bus_t *bus; bus_params_t *bp; urj_part_t *part; char buff[10]; int i; int failed = 0; bus = urj_bus_generic_new (chain, driver, sizeof (bus_params_t)); if (bus == NULL) return NULL; part = bus->part; bp = bus->params; /* default values */ bp->lbc_muxed = 0; bp->lbc_num_d = 8; bp->lbc_num_ad = 25; for (i = 0; cmd_params[i] != NULL; i++) { switch (cmd_params[i]->key) { case URJ_BUS_PARAM_KEY_HELP: urj_bus_generic_free (bus); urj_log (URJ_LOG_LEVEL_NORMAL, _("Usage: initbus mpc837x [mux] [width=WIDTH]\n" \ " MUX multiplexed data bus (default no)\n" \ " WIDTH data bus width - 8, 16, 32 (default 8)\n")); return NULL; case URJ_BUS_PARAM_KEY_MUX: bp->lbc_muxed = 1; break; case URJ_BUS_PARAM_KEY_WIDTH: switch (cmd_params[i]->value.lu) { case 8: bp->lbc_num_d = 8; break; case 16: bp->lbc_num_d = 16; break; case 32: bp->lbc_num_d = 32; break; default: urj_error_set (URJ_ERROR_UNSUPPORTED, _(" Only 8, 16, 32 bus width are suported\n")); } break; default: urj_bus_generic_free (bus); urj_error_set (URJ_ERROR_SYNTAX, "unrecognised bus parameter '%s'", \ urj_param_string(&urj_bus_param_list, cmd_params[i])); return NULL; } } if ((!bp->lbc_muxed) && (bp->lbc_num_d > 16)) { urj_bus_generic_free (bus); urj_error_set (URJ_ERROR_UNSUPPORTED, _(" Only 8 and 16 non multiplexed bus width are suported\n")); return NULL; } if (bp->lbc_muxed) bp->lbc_num_ad = 32; /* Get the signals */ if (bp->lbc_muxed) { failed |= urj_bus_generic_attach_sig( part, &(ALE), "LALE" ); for (i = 0; i < LBC_NUM_LAD; i++) { sprintf( buff, "LAD%d", i ); failed |= urj_bus_generic_attach_sig( part, &(LAD[i]), buff ); } } else { failed |= urj_bus_generic_attach_sig( part, &(LA[7]), "LDP2" ); failed |= urj_bus_generic_attach_sig( part, &(LA[8]), "LDP3" ); failed |= urj_bus_generic_attach_sig( part, &(LA[9]), "LGPL5" ); failed |= urj_bus_generic_attach_sig( part, &(LA[10]), "LALE" ); for (i = 11; i < 27; i++) { sprintf( buff, "LAD%d", i + 5 ); failed |= urj_bus_generic_attach_sig( part, &(LA[i]), buff ); } } for (i = 27; i < LBC_NUM_LAD; i++) { sprintf( buff, "LA%d", i ); failed |= urj_bus_generic_attach_sig( part, &(LA[i]), buff ); } for (i = 0; i < LBC_NUM_LCS; i++) { sprintf( buff, "LCS_B%d", i ); failed |= urj_bus_generic_attach_sig( part, &(nCS[i]), buff ); } for (i = 0; i < LBC_NUM_LWE; i++) { sprintf( buff, "LWE_B%d", i ); failed |= urj_bus_generic_attach_sig( part, &(nWE[i]), buff ); } failed |= urj_bus_generic_attach_sig( part, &(nOE), "LGPL2" ); failed |= urj_bus_generic_attach_sig( part, &(BCTL), "LBCTL" ); if (failed) { urj_bus_generic_free (bus); return NULL; } urj_log(URJ_LOG_LEVEL_NORMAL, "%sMUXed %db address, %db data bus\n", ((bp->lbc_muxed) ? "" : "Non-"), bp->lbc_num_ad, bp->lbc_num_d); return bus; }