// Update I2C log information for specified engine // i_op values: // LOC_ACQUIRE = OCC should take ownership of lock // LOC_RELEASE = OCC should release ownership of lock and notify host void update_i2c_lock(const lockOperation_e i_op, const uint8_t i_engine) { ocb_occflg_t occ_flags = {0}; #ifdef DEBUG_LOCK_TESTING ocb_occflg_t flag; flag.value = in32(OCB_OCCFLG); if (LOCK_RELEASE == i_op) { LOCK_DBG("update_i2c_lock: I2C engine %d RELEASE - host=%d, occ=%d, dimmTick=%d", i_engine, flag.fields.i2c_engine3_lock_host, flag.fields.i2c_engine3_lock_occ, DIMM_TICK); } else { LOCK_DBG("update_i2c_lock: I2C engine %d LOCK - host=%d, occ=%d, dimmTick=%d", i_engine, flag.fields.i2c_engine3_lock_host, flag.fields.i2c_engine3_lock_occ, DIMM_TICK); } #endif if (PIB_I2C_ENGINE_E == i_engine) { occ_flags.fields.i2c_engine3_lock_occ = 1; } else if (PIB_I2C_ENGINE_D == i_engine) { occ_flags.fields.i2c_engine2_lock_occ = 1; } else if (PIB_I2C_ENGINE_C == i_engine) { occ_flags.fields.i2c_engine1_lock_occ = 1; } if (LOCK_RELEASE == i_op) { out32(OCB_OCCFLG_CLR, occ_flags.value); // OCC had the lock and host wants it, so send interrupt to host notify_host(INTR_REASON_I2C_OWNERSHIP_CHANGE); TRAC_IMP("update_i2c_lock: OCC has released lock for I2C engine %d", i_engine); } else // LOCK_ACQUIRE { out32(OCB_OCCFLG_OR, occ_flags.value); TRAC_IMP("update_i2c_lock: OCC has acquired lock for I2C engine %d", i_engine); } } // end update_i2c_lock()
void SIMULATE_HOST() { static int lockDuration = DURATION_LOCK; // Unlock when this gets to 0 static int unlockDuration = DURATION_UNLOCK; // Request lock after this gets to 0 static int extIntDuration = DURATION_EXTINT; // Release external interrupt when this gets to 0 static int durationDelta = DURATION_LOCK_DELTA; // additional variability on how long lock is kept #if 1 // Force notifications (to ensure they are queued correctly static int newNotification = 45; // new notification every ticks if (--newNotification == 0) { ocb_occmisc_t current_occmisc0; current_occmisc0.value = in32(OCB_OCCMISC); TRAC_INFO("SIMULATE_HOST: forcing additional notifications (tmgt+tmgt+tmgt+shmem) currentInt=%d", current_occmisc0.fields.core_ext_intr); notify_host(INTR_REASON_HTMGT_SERVICE_REQUIRED); //notify_host(INTR_REASON_I2C_OWNERSHIP_CHANGE); notify_host(INTR_REASON_HTMGT_SERVICE_REQUIRED); notify_host(INTR_REASON_HTMGT_SERVICE_REQUIRED); notify_host(INTR_REASON_OPAL_SHARED_MEM_CHANGE); newNotification = 20; } #endif ocb_occflg_t occ_flags = {0}; occ_flags.value = in32(OCB_OCCFLG); if (occ_flags.fields.i2c_engine3_lock_host == 1) { if (occ_flags.fields.i2c_engine3_lock_occ == 0) { // Host owns lock if (--lockDuration == 0) { host_i2c_lock_release(); unlockDuration = DURATION_UNLOCK; } } else { // Host requested lock, but does not own it yet } } else { // Host has NOT requested lock yet if (--unlockDuration == 0) { // Request the lock host_i2c_lock_request(); lockDuration = DURATION_LOCK + durationDelta; if (--durationDelta < 0) { durationDelta = DURATION_LOCK_DELTA; } } } // Handle clearing the external interrupt periodically ocb_occmisc_t current_occmisc; current_occmisc.value = in32(OCB_OCCMISC); if (current_occmisc.fields.core_ext_intr) { if (--extIntDuration == 0) { TRAC_INFO("SIMULATE_HOST: clearing ext_intr"); current_occmisc.fields.core_ext_intr = 0; out32(OCB_OCCMISC,current_occmisc.value); extIntDuration = 2; } } }
static void detect_test_notify(struct comp_dev *dev) { notify_host(dev); notify_kpb(dev); }
int main(int argc, char **argv) { int c; int i; /* LDNS types */ ldns_pkt *notify; ldns_rr *question; ldns_resolver *res; ldns_rdf *ldns_zone_name = NULL; ldns_status status; const char *zone_name = NULL; int include_soa = 0; uint32_t soa_version = 0; ldns_tsig_credentials tsig_cred = {0,0,0}; int do_hexdump = 1; uint8_t *wire = NULL; size_t wiresize = 0; char *port = "53"; srandom(time(NULL) ^ getpid()); while ((c = getopt(argc, argv, "vhdp:r:s:y:z:")) != -1) { switch (c) { case 'd': verbose++; break; case 'p': port = optarg; break; case 'r': max_num_retry = atoi(optarg); break; case 's': include_soa = 1; soa_version = (uint32_t)atoi(optarg); break; case 'y': tsig_cred.algorithm = "hmac-md5.sig-alg.reg.int."; tsig_cred.keyname = optarg; tsig_cred.keydata = strchr(optarg, ':'); *tsig_cred.keydata = '\0'; tsig_cred.keydata++; printf("Sign with %s : %s\n", tsig_cred.keyname, tsig_cred.keydata); break; case 'z': zone_name = optarg; ldns_zone_name = ldns_dname_new_frm_str(zone_name); if(!ldns_zone_name) { printf("cannot parse zone name: %s\n", zone_name); exit(1); } break; case 'v': version(); case 'h': case '?': default: usage(); } } argc -= optind; argv += optind; if (argc == 0 || zone_name == NULL) { usage(); } notify = ldns_pkt_new(); question = ldns_rr_new(); res = ldns_resolver_new(); if (!notify || !question || !res) { /* bail out */ printf("error: cannot create ldns types\n"); exit(1); } /* create the rr for inside the pkt */ ldns_rr_set_class(question, LDNS_RR_CLASS_IN); ldns_rr_set_owner(question, ldns_zone_name); ldns_rr_set_type(question, LDNS_RR_TYPE_SOA); ldns_pkt_set_opcode(notify, LDNS_PACKET_NOTIFY); ldns_pkt_push_rr(notify, LDNS_SECTION_QUESTION, question); ldns_pkt_set_aa(notify, true); ldns_pkt_set_id(notify, random()&0xffff); if(include_soa) { char buf[10240]; ldns_rr *soa_rr=NULL; ldns_rdf *prev=NULL; snprintf(buf, sizeof(buf), "%s 3600 IN SOA . . %u 0 0 0 0", zone_name, (unsigned)soa_version); /*printf("Adding soa %s\n", buf);*/ status = ldns_rr_new_frm_str(&soa_rr, buf, 3600, NULL, &prev); if(status != LDNS_STATUS_OK) { printf("Error adding SOA version: %s\n", ldns_get_errorstr_by_id(status)); } ldns_pkt_push_rr(notify, LDNS_SECTION_ANSWER, soa_rr); } if(tsig_cred.keyname) { #ifdef HAVE_SSL status = ldns_pkt_tsig_sign(notify, tsig_cred.keyname, tsig_cred.keydata, 300, tsig_cred.algorithm, NULL); if(status != LDNS_STATUS_OK) { printf("Error TSIG sign query: %s\n", ldns_get_errorstr_by_id(status)); } #else fprintf(stderr, "Warning: TSIG needs OpenSSL support, which has not been compiled in, TSIG skipped\n"); #endif } if(verbose) { printf("# Sending packet:\n"); ldns_pkt_print(stdout, notify); } status = ldns_pkt2wire(&wire, notify, &wiresize); if(wiresize == 0) { printf("Error converting notify packet to hex.\n"); exit(1); } if(do_hexdump && verbose > 1) { printf("Hexdump of notify packet:\n"); for(i=0; i<(int)wiresize; i++) printf("%02x", (unsigned)wire[i]); printf("\n"); } for(i=0; i<argc; i++) { struct addrinfo hints, *res0, *res; int error; int default_family = AF_INET; if(verbose) printf("# sending to %s\n", argv[i]); memset(&hints, 0, sizeof(hints)); hints.ai_family = default_family; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; error = getaddrinfo(argv[i], port, &hints, &res0); if (error) { printf("skipping bad address: %s: %s\n", argv[i], gai_strerror(error)); continue; } for (res = res0; res; res = res->ai_next) { int s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if(s == -1) continue; /* send the notify */ notify_host(s, res, wire, wiresize, argv[i]); } freeaddrinfo(res0); } ldns_pkt_free(notify); free(wire); return 0; }