diff --git a/BaS_gcc/include/eth.h b/BaS_gcc/include/eth.h index 424bc39..dc3b127 100644 --- a/BaS_gcc/include/eth.h +++ b/BaS_gcc/include/eth.h @@ -40,16 +40,16 @@ typedef uint16_t ETH_FRM_TYPE; /* Ethernet Frame Header definition */ typedef struct { - ETH_ADDR dest; - ETH_ADDR src; - ETH_FRM_TYPE type; + ETH_ADDR dest; + ETH_ADDR src; + ETH_FRM_TYPE type; } ETH_HDR; /* Ethernet Frame definition */ typedef struct { - ETH_HDR head; - uint8_t* data; + ETH_HDR head; + uint8_t* data; } ETH_FRAME; /*******************************************************************/ diff --git a/BaS_gcc/include/nif.h b/BaS_gcc/include/nif.h index e74283b..639d341 100644 --- a/BaS_gcc/include/nif.h +++ b/BaS_gcc/include/nif.h @@ -1,62 +1,49 @@ -/* - * File: nif.h - * Purpose: Definition of a Network InterFace. - * - * Notes: - */ - -#ifndef _NIF_H -#define _NIF_H - -/********************************************************************/ - -/* - * Maximum number of supported protoocls: IP, ARP, RARP - */ -#define MAX_SUP_PROTO (3) - -typedef struct NIF_t -{ - ETH_ADDR hwa; /* ethernet card hardware address */ - ETH_ADDR broadcast; /* broadcast address */ - int mtu; /* hardware maximum transmission unit */ - int ch; /* ethernet channel associated with this NIF */ - - struct SUP_PROTO_t - { - uint16_t protocol; - void (*handler)(struct NIF_t *, NBUF *); - void *info; - } protocol[MAX_SUP_PROTO]; - - unsigned short num_protocol; - - int (*send)(struct NIF_t *, uint8_t *, uint8_t *, uint16_t, NBUF *); - - unsigned int f_rx; - unsigned int f_tx; - unsigned int f_rx_err; - unsigned int f_tx_err; - unsigned int f_err; -} NIF; - -/********************************************************************/ - -NIF * -nif_init (NIF *); - -int -nif_protocol_exist (NIF *, uint16_t); - -void -nif_protocol_handler (NIF *, uint16_t, NBUF *); - -void * -nif_get_protocol_info (NIF *, uint16_t); - -int -nif_bind_protocol (NIF *, uint16_t, void (*)(NIF *, NBUF *), void *); - -/********************************************************************/ - -#endif /* _NIF_H */ +/* + * File: nif.h + * Purpose: Definition of a Network InterFace. + * + * Notes: + */ + +#ifndef _NIF_H +#define _NIF_H + +/* + * Maximum number of supported protoocls: IP, ARP, RARP + */ +#define MAX_SUP_PROTO (3) + +typedef struct NIF_t +{ + ETH_ADDR hwa; /* ethernet card hardware address */ + ETH_ADDR broadcast; /* broadcast address */ + int mtu; /* hardware maximum transmission unit */ + int ch; /* ethernet channel associated with this NIF */ + + struct SUP_PROTO_t + { + uint16_t protocol; + void (*handler)(struct NIF_t *, NBUF *); + void *info; + } protocol[MAX_SUP_PROTO]; + + unsigned short num_protocol; + + int (*send)(struct NIF_t *, uint8_t *, uint8_t *, uint16_t, NBUF *); + + unsigned int f_rx; + unsigned int f_tx; + unsigned int f_rx_err; + unsigned int f_tx_err; + unsigned int f_err; +} NIF; + + +extern NIF *nif_init (NIF *); +extern int nif_protocol_exist (NIF *, uint16_t); +extern void nif_protocol_handler (NIF *, uint16_t, NBUF *); +extern void *nif_get_protocol_info (NIF *, uint16_t); +extern int nif_bind_protocol (NIF *, uint16_t, void (*)(NIF *, NBUF *), void *); + + +#endif /* _NIF_H */ diff --git a/BaS_gcc/net/arp.c b/BaS_gcc/net/arp.c index 07072d6..e9669e1 100644 --- a/BaS_gcc/net/arp.c +++ b/BaS_gcc/net/arp.c @@ -13,450 +13,451 @@ static uint8_t *arp_find_pair(ARP_INFO *arptab, uint16_t protocol, uint8_t *hwa, uint8_t *pa) { - /* - * This function searches through the ARP table for the - * specified or address pair. - * If it is found, then a a pointer to the non-specified - * address is returned. Otherwise NULL is returned. - * If you pass in then you get out. - * If you pass in then you get out. - */ - int slot, i, match = false; - uint8_t *rvalue; + /* + * This function searches through the ARP table for the + * specified or address pair. + * If it is found, then a a pointer to the non-specified + * address is returned. Otherwise NULL is returned. + * If you pass in then you get out. + * If you pass in then you get out. + */ + int slot, i, match = false; + uint8_t *rvalue; - if (((hwa == 0) && (pa == 0)) || (arptab == 0)) - return NULL; + if (((hwa == 0) && (pa == 0)) || (arptab == 0)) + return NULL; - rvalue = NULL; + rvalue = NULL; - /* - * Check each protocol address for a match - */ - for (slot = 0; slot < arptab->tab_size; slot++) - { - if ((arptab->table[slot].longevity != ARP_ENTRY_EMPTY) && - (arptab->table[slot].protocol == protocol)) - { - match = true; - if (hwa != 0) - { - /* - * Check the Hardware Address field - */ - rvalue = &arptab->table[slot].pa[0]; - for (i = 0; i < arptab->table[slot].hwa_size; i++) - { - if (arptab->table[slot].hwa[i] != hwa[i]) - { - match = false; - break; - } - } - } - else - { - /* - * Check the Protocol Address field - */ - rvalue = &arptab->table[slot].hwa[0]; - for (i = 0; i < arptab->table[slot].pa_size; i++) - { - if (arptab->table[slot].pa[i] != pa[i]) - { - match = false; - break; - } - } - } - if (match) - { - break; - } - } - } + /* + * Check each protocol address for a match + */ + for (slot = 0; slot < arptab->tab_size; slot++) + { + if ((arptab->table[slot].longevity != ARP_ENTRY_EMPTY) && + (arptab->table[slot].protocol == protocol)) + { + match = true; + if (hwa != 0) + { + /* + * Check the Hardware Address field + */ + rvalue = &arptab->table[slot].pa[0]; + for (i = 0; i < arptab->table[slot].hwa_size; i++) + { + if (arptab->table[slot].hwa[i] != hwa[i]) + { + match = false; + break; + } + } + } + else + { + /* + * Check the Protocol Address field + */ + rvalue = &arptab->table[slot].hwa[0]; + for (i = 0; i < arptab->table[slot].pa_size; i++) + { + if (arptab->table[slot].pa[i] != pa[i]) + { + match = false; + break; + } + } + } + if (match) + { + break; + } + } + } - if (match) - return rvalue; - else - return NULL; + if (match) + return rvalue; + else + return NULL; } void arp_merge(ARP_INFO *arptab, uint16_t protocol, int hwa_size, uint8_t *hwa, - int pa_size, uint8_t *pa, int longevity) + int pa_size, uint8_t *pa, int longevity) { - /* - * This function merges an entry into the ARP table. If - * either piece is NULL, the function exits, otherwise - * the entry is merged or added, provided there is space. - */ - int i, slot; - uint8_t *ta; + /* + * This function merges an entry into the ARP table. If + * either piece is NULL, the function exits, otherwise + * the entry is merged or added, provided there is space. + */ + int i, slot; + uint8_t *ta; - if ((hwa == NULL) || (pa == NULL) || (arptab == NULL) || - ((longevity != ARP_ENTRY_TEMP) && - (longevity != ARP_ENTRY_PERM))) - { - return; - } + if ((hwa == NULL) || (pa == NULL) || (arptab == NULL) || + ((longevity != ARP_ENTRY_TEMP) && + (longevity != ARP_ENTRY_PERM))) + { + return; + } - /* First search ARP table for existing entry */ - if ((ta = arp_find_pair(arptab,protocol,NULL,pa)) != 0) - { - /* Update hardware address */ - for (i = 0; i < hwa_size; i++) - ta[i] = hwa[i]; - return; - } - - /* Next try to find an empty slot */ - slot = -1; - for (i = 0; i < MAX_ARP_ENTRY; i++) - { - if (arptab->table[i].longevity == ARP_ENTRY_EMPTY) - { - slot = i; - break; - } - } + /* First search ARP table for existing entry */ + if ((ta = arp_find_pair(arptab,protocol,NULL,pa)) != 0) + { + /* Update hardware address */ + for (i = 0; i < hwa_size; i++) + ta[i] = hwa[i]; + return; + } - /* if no empty slot was found, pick a temp slot */ - if (slot == -1) - { - for (i = 0; i < MAX_ARP_ENTRY; i++) - { - if (arptab->table[i].longevity == ARP_ENTRY_TEMP) - { - slot = i; - break; - } - } - } + /* Next try to find an empty slot */ + slot = -1; + for (i = 0; i < MAX_ARP_ENTRY; i++) + { + if (arptab->table[i].longevity == ARP_ENTRY_EMPTY) + { + slot = i; + break; + } + } - /* if after all this, still no slot found, add in last slot */ - if (slot == -1) - slot = (MAX_ARP_ENTRY - 1); + /* if no empty slot was found, pick a temp slot */ + if (slot == -1) + { + for (i = 0; i < MAX_ARP_ENTRY; i++) + { + if (arptab->table[i].longevity == ARP_ENTRY_TEMP) + { + slot = i; + break; + } + } + } - /* add the entry into the slot */ - arptab->table[slot].protocol = protocol; + /* if after all this, still no slot found, add in last slot */ + if (slot == -1) + slot = (MAX_ARP_ENTRY - 1); - arptab->table[slot].hwa_size = (uint8_t) hwa_size; - for (i = 0; i < hwa_size; i++) - arptab->table[slot].hwa[i] = hwa[i]; + /* add the entry into the slot */ + arptab->table[slot].protocol = protocol; - arptab->table[slot].pa_size = (uint8_t) pa_size; - for (i = 0; i < pa_size; i++) - arptab->table[slot].pa[i] = pa[i]; + arptab->table[slot].hwa_size = (uint8_t) hwa_size; + for (i = 0; i < hwa_size; i++) + arptab->table[slot].hwa[i] = hwa[i]; - arptab->table[slot].longevity = longevity; + arptab->table[slot].pa_size = (uint8_t) pa_size; + for (i = 0; i < pa_size; i++) + arptab->table[slot].pa[i] = pa[i]; + + arptab->table[slot].longevity = longevity; } void arp_remove(ARP_INFO *arptab, uint16_t protocol, uint8_t *hwa, uint8_t *pa) { - /* - * This function removes an entry from the ARP table. The - * ARP table is searched according to the non-NULL address - * that is provided. - */ - int slot, i, match; + /* + * This function removes an entry from the ARP table. The + * ARP table is searched according to the non-NULL address + * that is provided. + */ + int slot, i, match; - if (((hwa == 0) && (pa == 0)) || (arptab == 0)) - return; + if (((hwa == 0) && (pa == 0)) || (arptab == 0)) + return; - /* check each hardware adress for a match */ - for (slot = 0; slot < arptab->tab_size; slot++) - { - if ((arptab->table[slot].longevity != ARP_ENTRY_EMPTY) && - (arptab->table[slot].protocol == protocol)) - { - match = true; - if (hwa != 0) - { - /* Check Hardware Address field */ - for (i = 0; i < arptab->table[slot].hwa_size; i++) - { - if (arptab->table[slot].hwa[i] != hwa[i]) - { - match = false; - break; - } - } - } - else - { - /* Check Protocol Address field */ - for (i = 0; i < arptab->table[slot].pa_size; i++) - { - if (arptab->table[slot].pa[i] != pa[i]) - { - match = false; - break; - } - } - } - if (match) - { - for (i = 0; i < arptab->table[slot].hwa_size; i++) - arptab->table[slot].hwa[i] = 0; - for (i = 0; i < arptab->table[slot].pa_size; i++) - arptab->table[slot].pa[i] = 0; - arptab->table[slot].longevity = ARP_ENTRY_EMPTY; - break; - } - } - } + /* check each hardware adress for a match */ + for (slot = 0; slot < arptab->tab_size; slot++) + { + if ((arptab->table[slot].longevity != ARP_ENTRY_EMPTY) && + (arptab->table[slot].protocol == protocol)) + { + match = true; + if (hwa != 0) + { + /* Check Hardware Address field */ + for (i = 0; i < arptab->table[slot].hwa_size; i++) + { + if (arptab->table[slot].hwa[i] != hwa[i]) + { + match = false; + break; + } + } + } + else + { + /* Check Protocol Address field */ + for (i = 0; i < arptab->table[slot].pa_size; i++) + { + if (arptab->table[slot].pa[i] != pa[i]) + { + match = false; + break; + } + } + } + if (match) + { + for (i = 0; i < arptab->table[slot].hwa_size; i++) + arptab->table[slot].hwa[i] = 0; + for (i = 0; i < arptab->table[slot].pa_size; i++) + arptab->table[slot].pa[i] = 0; + arptab->table[slot].longevity = ARP_ENTRY_EMPTY; + break; + } + } + } } void arp_request(NIF *nif, uint8_t *pa) { - /* - * This function broadcasts an ARP request for the protocol - * address "pa" - */ - uint8_t *addr; - NBUF *pNbuf; - arp_frame_hdr *arpframe; - int i, result; + /* + * This function broadcasts an ARP request for the protocol + * address "pa" + */ + uint8_t *addr; + NBUF *pNbuf; + arp_frame_hdr *arpframe; + int i, result; - pNbuf = nbuf_alloc(); - if (pNbuf == NULL) - { - #if defined(DEBUG_PRINT) - printf("ARP: arp_request couldn't allocate Tx buffer\n"); - #endif - return; - } - arpframe = (arp_frame_hdr *)&pNbuf->data[ARP_HDR_OFFSET]; + xprintf("%s\r\n", __FUNCTION__); - /* Build the ARP request packet */ - arpframe->ar_hrd = ETHERNET; - arpframe->ar_pro = ETH_FRM_IP; - arpframe->ar_hln = 6; - arpframe->ar_pln = 4; - arpframe->opcode = ARP_REQUEST; + pNbuf = nbuf_alloc(); + if (pNbuf == NULL) + { + xprintf("ARP: arp_request couldn't allocate Tx buffer\n"); + return; + } - addr = &nif->hwa[0]; - for (i = 0; i < 6; i++) - arpframe->ar_sha[i] = addr[i]; + arpframe = (arp_frame_hdr *)&pNbuf->data[ARP_HDR_OFFSET]; - addr = ip_get_myip(nif_get_protocol_info(nif,ETH_FRM_IP)); - for (i = 0; i < 4; i++) - arpframe->ar_spa[i] = addr[i]; + /* Build the ARP request packet */ + arpframe->ar_hrd = ETHERNET; + arpframe->ar_pro = ETH_FRM_IP; + arpframe->ar_hln = 6; + arpframe->ar_pln = 4; + arpframe->opcode = ARP_REQUEST; - for (i = 0; i < 6; i++) - arpframe->ar_tha[i] = 0x00; + addr = &nif->hwa[0]; + for (i = 0; i < 6; i++) + arpframe->ar_sha[i] = addr[i]; - for (i = 0; i < 4; i++) - arpframe->ar_tpa[i] = pa[i]; + addr = ip_get_myip(nif_get_protocol_info(nif,ETH_FRM_IP)); + for (i = 0; i < 4; i++) + arpframe->ar_spa[i] = addr[i]; - pNbuf->length = ARP_HDR_LEN; + for (i = 0; i < 6; i++) + arpframe->ar_tha[i] = 0x00; - /* Send the ARP request */ - result = nif->send(nif, nif->broadcast, nif->hwa, ETH_FRM_ARP, pNbuf); + for (i = 0; i < 4; i++) + arpframe->ar_tpa[i] = pa[i]; - if (result == 0) - nbuf_free(pNbuf); + pNbuf->length = ARP_HDR_LEN; + + /* Send the ARP request */ + result = nif->send(nif, nif->broadcast, nif->hwa, ETH_FRM_ARP, pNbuf); + + if (result == 0) + nbuf_free(pNbuf); } static int arp_resolve_pa(NIF *nif, uint16_t protocol, uint8_t *pa, uint8_t **ha) { - /* - * This function accepts a pointer to a protocol address and - * searches the ARP table for a hardware address match. If no - * no match found, false is returned. - */ - ARP_INFO *arptab; + /* + * This function accepts a pointer to a protocol address and + * searches the ARP table for a hardware address match. If no + * no match found, false is returned. + */ + ARP_INFO *arptab; - if ((pa == NULL) || (nif == NULL) || (protocol == 0)) - return 0; + if ((pa == NULL) || (nif == NULL) || (protocol == 0)) + return 0; - arptab = nif_get_protocol_info (nif,ETH_FRM_ARP); - *ha = arp_find_pair(arptab,protocol,0,pa); + arptab = nif_get_protocol_info (nif,ETH_FRM_ARP); + *ha = arp_find_pair(arptab,protocol,0,pa); - if (*ha == NULL) - return 0; - else - return 1; + if (*ha == NULL) + return 0; + else + return 1; } uint8_t *arp_resolve(NIF *nif, uint16_t protocol, uint8_t *pa) { - int i; - uint8_t *hwa; + int i; + uint8_t *hwa; - /* - * Check to see if the necessary MAC-to-IP translation information - * is in table already - */ - if (arp_resolve_pa (nif, protocol, pa, &hwa)) - return hwa; + /* + * Check to see if the necessary MAC-to-IP translation information + * is in table already + */ + if (arp_resolve_pa (nif, protocol, pa, &hwa)) + return hwa; - /* - * Ok, it's not, so we need to try to obtain it by broadcasting - * an ARP request. Hopefully the desired host is listening and - * will respond with it's MAC address - */ - for (i = 0; i < 3; i++) - { - arp_request (nif, pa); + /* + * Ok, it's not, so we need to try to obtain it by broadcasting + * an ARP request. Hopefully the desired host is listening and + * will respond with it's MAC address + */ + for (i = 0; i < 3; i++) + { + arp_request (nif, pa); - timer_set_secs(TIMER_NETWORK, ARP_TIMEOUT); - while (timer_get_reference(TIMER_NETWORK)) - { - if (arp_resolve_pa (nif, protocol, pa, &hwa)) - return hwa; - } - } + timer_set_secs(TIMER_NETWORK, ARP_TIMEOUT); + while (timer_get_reference(TIMER_NETWORK)) + { + if (arp_resolve_pa (nif, protocol, pa, &hwa)) + return hwa; + } + } - return NULL; + return NULL; } void arp_init(ARP_INFO *arptab) { - int slot, i; + int slot, i; - arptab->tab_size = MAX_ARP_ENTRY; - for (slot = 0; slot < arptab->tab_size; slot++) - { - for (i = 0; i < MAX_HWA_SIZE; i++) - arptab->table[slot].hwa[i] = 0; - for (i = 0; i < MAX_PA_SIZE; i++) - arptab->table[slot].pa[i] = 0; - arptab->table[slot].longevity = ARP_ENTRY_EMPTY; - arptab->table[slot].hwa_size = 0; - arptab->table[slot].pa_size = 0; - } + arptab->tab_size = MAX_ARP_ENTRY; + for (slot = 0; slot < arptab->tab_size; slot++) + { + for (i = 0; i < MAX_HWA_SIZE; i++) + arptab->table[slot].hwa[i] = 0; + for (i = 0; i < MAX_PA_SIZE; i++) + arptab->table[slot].pa[i] = 0; + arptab->table[slot].longevity = ARP_ENTRY_EMPTY; + arptab->table[slot].hwa_size = 0; + arptab->table[slot].pa_size = 0; + } } void arp_handler(NIF *nif, NBUF *pNbuf) { - /* - * ARP protocol handler - */ - uint8_t *addr; - ARP_INFO *arptab; - int longevity; - arp_frame_hdr *rx_arpframe, *tx_arpframe; + /* + * ARP protocol handler + */ + uint8_t *addr; + ARP_INFO *arptab; + int longevity; + arp_frame_hdr *rx_arpframe, *tx_arpframe; - arptab = nif_get_protocol_info(nif, ETH_FRM_ARP); - rx_arpframe = (arp_frame_hdr *) &pNbuf->data[pNbuf->offset]; + arptab = nif_get_protocol_info(nif, ETH_FRM_ARP); + rx_arpframe = (arp_frame_hdr *) &pNbuf->data[pNbuf->offset]; - /* - * Check for an appropriate ARP packet - */ - if ((pNbuf->length < ARP_HDR_LEN) || - (rx_arpframe->ar_hrd != ETHERNET) || - (rx_arpframe->ar_hln != 6) || - (rx_arpframe->ar_pro != ETH_FRM_IP) || - (rx_arpframe->ar_pln != 4)) - { - nbuf_free(pNbuf); - return; - } + /* + * Check for an appropriate ARP packet + */ + if ((pNbuf->length < ARP_HDR_LEN) || + (rx_arpframe->ar_hrd != ETHERNET) || + (rx_arpframe->ar_hln != 6) || + (rx_arpframe->ar_pro != ETH_FRM_IP) || + (rx_arpframe->ar_pln != 4)) + { + nbuf_free(pNbuf); + return; + } - /* - * Check to see if it was addressed to me - if it was, keep this - * ARP entry in the table permanently; if not, mark it so that it - * can be displaced later if necessary - */ - addr = ip_get_myip(nif_get_protocol_info(nif,ETH_FRM_IP)); - if ((rx_arpframe->ar_tpa[0] == addr[0]) && - (rx_arpframe->ar_tpa[1] == addr[1]) && - (rx_arpframe->ar_tpa[2] == addr[2]) && - (rx_arpframe->ar_tpa[3] == addr[3]) ) - { - longevity = ARP_ENTRY_PERM; - } - else - longevity = ARP_ENTRY_TEMP; + /* + * Check to see if it was addressed to me - if it was, keep this + * ARP entry in the table permanently; if not, mark it so that it + * can be displaced later if necessary + */ + addr = ip_get_myip(nif_get_protocol_info(nif,ETH_FRM_IP)); + if ((rx_arpframe->ar_tpa[0] == addr[0]) && + (rx_arpframe->ar_tpa[1] == addr[1]) && + (rx_arpframe->ar_tpa[2] == addr[2]) && + (rx_arpframe->ar_tpa[3] == addr[3]) ) + { + longevity = ARP_ENTRY_PERM; + } + else + longevity = ARP_ENTRY_TEMP; - /* - * Add ARP info into the table - */ - arp_merge(arptab, - rx_arpframe->ar_pro, - rx_arpframe->ar_hln, - &rx_arpframe->ar_sha[0], - rx_arpframe->ar_pln, - &rx_arpframe->ar_spa[0], - longevity - ); + /* + * Add ARP info into the table + */ + arp_merge(arptab, + rx_arpframe->ar_pro, + rx_arpframe->ar_hln, + &rx_arpframe->ar_sha[0], + rx_arpframe->ar_pln, + &rx_arpframe->ar_spa[0], + longevity + ); - switch (rx_arpframe->opcode) - { - case ARP_REQUEST: - /* - * Check to see if request is directed to me - */ - if ((rx_arpframe->ar_tpa[0] == addr[0]) && - (rx_arpframe->ar_tpa[1] == addr[1]) && - (rx_arpframe->ar_tpa[2] == addr[2]) && - (rx_arpframe->ar_tpa[3] == addr[3]) ) - { - /* - * Reuse the current network buffer to assemble an ARP reply - */ - tx_arpframe = (arp_frame_hdr *)&pNbuf->data[ARP_HDR_OFFSET]; + switch (rx_arpframe->opcode) + { + case ARP_REQUEST: + /* + * Check to see if request is directed to me + */ + if ((rx_arpframe->ar_tpa[0] == addr[0]) && + (rx_arpframe->ar_tpa[1] == addr[1]) && + (rx_arpframe->ar_tpa[2] == addr[2]) && + (rx_arpframe->ar_tpa[3] == addr[3]) ) + { + /* + * Reuse the current network buffer to assemble an ARP reply + */ + tx_arpframe = (arp_frame_hdr *)&pNbuf->data[ARP_HDR_OFFSET]; - /* - * Build new ARP frame from the received data - */ - tx_arpframe->ar_hrd = ETHERNET; - tx_arpframe->ar_pro = ETH_FRM_IP; - tx_arpframe->ar_hln = 6; - tx_arpframe->ar_pln = 4; - tx_arpframe->opcode = ARP_REPLY; - tx_arpframe->ar_tha[0] = rx_arpframe->ar_sha[0]; - tx_arpframe->ar_tha[1] = rx_arpframe->ar_sha[1]; - tx_arpframe->ar_tha[2] = rx_arpframe->ar_sha[2]; - tx_arpframe->ar_tha[3] = rx_arpframe->ar_sha[3]; - tx_arpframe->ar_tha[4] = rx_arpframe->ar_sha[4]; - tx_arpframe->ar_tha[5] = rx_arpframe->ar_sha[5]; - tx_arpframe->ar_tpa[0] = rx_arpframe->ar_spa[0]; - tx_arpframe->ar_tpa[1] = rx_arpframe->ar_spa[1]; - tx_arpframe->ar_tpa[2] = rx_arpframe->ar_spa[2]; - tx_arpframe->ar_tpa[3] = rx_arpframe->ar_spa[3]; + /* + * Build new ARP frame from the received data + */ + tx_arpframe->ar_hrd = ETHERNET; + tx_arpframe->ar_pro = ETH_FRM_IP; + tx_arpframe->ar_hln = 6; + tx_arpframe->ar_pln = 4; + tx_arpframe->opcode = ARP_REPLY; + tx_arpframe->ar_tha[0] = rx_arpframe->ar_sha[0]; + tx_arpframe->ar_tha[1] = rx_arpframe->ar_sha[1]; + tx_arpframe->ar_tha[2] = rx_arpframe->ar_sha[2]; + tx_arpframe->ar_tha[3] = rx_arpframe->ar_sha[3]; + tx_arpframe->ar_tha[4] = rx_arpframe->ar_sha[4]; + tx_arpframe->ar_tha[5] = rx_arpframe->ar_sha[5]; + tx_arpframe->ar_tpa[0] = rx_arpframe->ar_spa[0]; + tx_arpframe->ar_tpa[1] = rx_arpframe->ar_spa[1]; + tx_arpframe->ar_tpa[2] = rx_arpframe->ar_spa[2]; + tx_arpframe->ar_tpa[3] = rx_arpframe->ar_spa[3]; - /* - * Now copy in the new information - */ - addr = &nif->hwa[0]; - tx_arpframe->ar_sha[0] = addr[0]; - tx_arpframe->ar_sha[1] = addr[1]; - tx_arpframe->ar_sha[2] = addr[2]; - tx_arpframe->ar_sha[3] = addr[3]; - tx_arpframe->ar_sha[4] = addr[4]; - tx_arpframe->ar_sha[5] = addr[5]; + /* + * Now copy in the new information + */ + addr = &nif->hwa[0]; + tx_arpframe->ar_sha[0] = addr[0]; + tx_arpframe->ar_sha[1] = addr[1]; + tx_arpframe->ar_sha[2] = addr[2]; + tx_arpframe->ar_sha[3] = addr[3]; + tx_arpframe->ar_sha[4] = addr[4]; + tx_arpframe->ar_sha[5] = addr[5]; - addr = ip_get_myip(nif_get_protocol_info(nif,ETH_FRM_IP)); - tx_arpframe->ar_spa[0] = addr[0]; - tx_arpframe->ar_spa[1] = addr[1]; - tx_arpframe->ar_spa[2] = addr[2]; - tx_arpframe->ar_spa[3] = addr[3]; + addr = ip_get_myip(nif_get_protocol_info(nif,ETH_FRM_IP)); + tx_arpframe->ar_spa[0] = addr[0]; + tx_arpframe->ar_spa[1] = addr[1]; + tx_arpframe->ar_spa[2] = addr[2]; + tx_arpframe->ar_spa[3] = addr[3]; - /* - * Save the length of my packet in the buffer structure - */ - pNbuf->length = ARP_HDR_LEN; - - nif->send(nif, - &tx_arpframe->ar_tha[0], - &tx_arpframe->ar_sha[0], - ETH_FRM_ARP, - pNbuf); - } - else - nbuf_free(pNbuf); - break; - case ARP_REPLY: - /* - * The ARP Reply case is already taken care of - */ - default: - nbuf_free(pNbuf); - break; - } + /* + * Save the length of my packet in the buffer structure + */ + pNbuf->length = ARP_HDR_LEN; - return; + nif->send(nif, + &tx_arpframe->ar_tha[0], + &tx_arpframe->ar_sha[0], + ETH_FRM_ARP, + pNbuf); + } + else + nbuf_free(pNbuf); + break; + case ARP_REPLY: + /* + * The ARP Reply case is already taken care of + */ + default: + nbuf_free(pNbuf); + break; + } + + return; } diff --git a/BaS_gcc/net/bootp.c b/BaS_gcc/net/bootp.c index f460e4d..f7e0b1a 100644 --- a/BaS_gcc/net/bootp.c +++ b/BaS_gcc/net/bootp.c @@ -56,15 +56,22 @@ void bootp_request(NIF *nif, uint8_t *pa) nbuf->length = BOOTP_PACKET_LEN; + /* setup reply handler */ + udp_bind_port(BOOTP_CLIENT_PORT, bootp_handler); + for (i = 0; i < MAX_TRIES; i++) { /* Send the BOOTP request */ result = udp_send(connection.nif, broadcast, BOOTP_CLIENT_PORT, BOOTP_SERVER_PORT, nbuf); + xprintf("sent bootp request\r\n"); if (result == true) break; } + /* release handler */ + udp_free_port(BOOTP_CLIENT_PORT); + if (result == 0) nbuf_free(nbuf); } @@ -85,6 +92,7 @@ void bootp_handler(NIF *nif, NBUF *nbuf) if (rx_p->type == BOOTP_TYPE_BOOTREPLY && rx_p->xid == XID) { + xprintf("received bootp reply\r\n"); /* seems to be valid */ } diff --git a/BaS_gcc/net/fec.c b/BaS_gcc/net/fec.c index f3db7fe..4b090f4 100644 --- a/BaS_gcc/net/fec.c +++ b/BaS_gcc/net/fec.c @@ -1025,7 +1025,7 @@ void fec1_tx_frame(void) * 1 success * 0 otherwise */ -int fec_send (uint8_t ch, NIF *nif, uint8_t *dst, uint8_t *src, uint16_t type, NBUF *nbuf) +int fec_send(uint8_t ch, NIF *nif, uint8_t *dst, uint8_t *src, uint16_t type, NBUF *nbuf) { FECBD *pTxBD; diff --git a/BaS_gcc/net/ip.c b/BaS_gcc/net/ip.c index e285183..0c2ae8e 100644 --- a/BaS_gcc/net/ip.c +++ b/BaS_gcc/net/ip.c @@ -147,20 +147,21 @@ int ip_send(NIF *nif, uint8_t *dest, uint8_t *src, uint8_t protocol, NBUF *pNbuf /* * Determine the hardware address of the recipient */ - route = ip_resolve_route(nif, dest); - if (route == NULL) - { - xprintf("Unable to locate %d.%d.%d.%d\n", - dest[0], dest[1], dest[2], dest[3]); - return 0; - } + IP_ADDR bc = { 255, 255, 255, 255}; + if (memcmp(bc, dest, 4) != 0) + { + route = ip_resolve_route(nif, dest); + if (route == NULL) + { + xprintf("Unable to locate %d.%d.%d.%d\n", + dest[0], dest[1], dest[2], dest[3]); + return 0; + } + } + else + route = bc; - return nif->send(nif, - route, - &nif->hwa[0], - ETH_FRM_IP, - pNbuf - ); + return nif->send(nif, route, &nif->hwa[0], ETH_FRM_IP, pNbuf); } #if defined(DEBUG_PRINT) diff --git a/BaS_gcc/net/nbuf.c b/BaS_gcc/net/nbuf.c index 4684c8b..8419770 100644 --- a/BaS_gcc/net/nbuf.c +++ b/BaS_gcc/net/nbuf.c @@ -1,213 +1,211 @@ -/* - * File: nbuf.c - * Purpose: Implementation of network buffer scheme. - * - * Notes: - */ -#include "queue.h" -#include "net.h" -#include "driver_mem.h" -#include "exceptions.h" -#include "bas_types.h" -#include "bas_printf.h" -/* - * Queues used for network buffer storage - */ -QUEUE nbuf_queue[NBUF_MAXQ]; - -/* - * Some devices require line-aligned buffers. In order to accomplish - * this, the nbuf data is over-allocated and adjusted. The following - * array keeps track of the original data pointer returned by malloc - */ -uint8_t *unaligned_buffers[NBUF_MAX]; - -/* - * Initialize all the network buffer queues - * - * Return Value: - * 0 success - * 1 failure - */ -int nbuf_init(void) -{ - int i; - NBUF *nbuf; - - for (i=0; idata = (uint8_t *)((uint32_t)(unaligned_buffers[i] + 15) & 0xFFFFFFF0); - if (!nbuf->data) - { - return 1; - } - - /* Initialize the network buffer */ - nbuf->offset = 0; - nbuf->length = 0; - - /* Add the network buffer to the free list */ - queue_add(&nbuf_queue[NBUF_FREE], (QNODE *)nbuf); - } - - #ifdef DEBUG_PRINT - printf("NBUF allocation complete\n"); - nbuf_debug_dump(); - #endif - - return 0; -} - -/* - * Return all the allocated memory to the heap - */ -void nbuf_flush(void) -{ - NBUF *nbuf; - int i, level = set_ipl(7); - int n = 0; - - for (i = 0; i < NBUF_MAX; ++i) - driver_mem_free((uint8_t *) unaligned_buffers[i]); - - for (i = 0; i < NBUF_MAXQ; ++i) - { - while ((nbuf = (NBUF *) queue_remove(&nbuf_queue[i])) != NULL) - { - driver_mem_free(nbuf); - ++n; - } - } - set_ipl(level); -} - -/* - * Allocate a network buffer from the free list - * - * Return Value: - * Pointer to a free network buffer - * NULL if none are available - */ -NBUF *nbuf_alloc(void) -{ - NBUF *nbuf; - int level = set_ipl(7); - - nbuf = (NBUF *) queue_remove(&nbuf_queue[NBUF_FREE]); - set_ipl(level); - - return nbuf; -} - -/* - * Add the specified network buffer back to the free list - * - * Parameters: - * nbuf Buffer to add back to the free list - */ -void nbuf_free(NBUF *nbuf) -{ - int level = set_ipl(7); - - nbuf->offset = 0; - nbuf->length = NBUF_SZ; - queue_add(&nbuf_queue[NBUF_FREE],(QNODE *)nbuf); - - set_ipl(level); -} - -/* - * Remove a network buffer from the specified queue - * - * Parameters: - * q The index that identifies the queue to pull the buffer from - */ -NBUF *nbuf_remove(int q) -{ - NBUF *nbuf; - int level = set_ipl(7); - - nbuf = (NBUF *) queue_remove(&nbuf_queue[q]); - set_ipl(level); - - return nbuf; -} - -/* - * Add a network buffer to the specified queue - * - * Parameters: - * q The index that identifies the queue to add the buffer to - */ -void nbuf_add(int q, NBUF *nbuf) -{ - int level = set_ipl(7); - queue_add(&nbuf_queue[q],(QNODE *)nbuf); - set_ipl(level); -} - -/* - * Put all the network buffers back into the free list - */ -void nbuf_reset(void) -{ - NBUF *nbuf; - int i, level = set_ipl(7); - - for (i = 1; i < NBUF_MAXQ; ++i) - { - while ((nbuf = nbuf_remove(i)) != NULL) - nbuf_free(nbuf); - } - set_ipl(level); -} - -/* - * Display all the nbuf queues - */ -void nbuf_debug_dump(void) -{ -#ifdef DEBUG - NBUF *nbuf; - int i, j, level; - - level = set_ipl(7); - - for (i = 0; i < NBUF_MAXQ; ++i) - { - printf("\n\nQueue #%d\n\n",i); - printf("\tBuffer Location\tOffset\tLength\n"); - printf("--------------------------------------\n"); - j = 0; - nbuf = (NBUF *)queue_peek(&nbuf_queue[i]); - while (nbuf != NULL) - { - printf("%d\t 0x%08x\t0x%04x\t0x%04x\n",j++,nbuf->data, - nbuf->offset, - nbuf->length); - nbuf = (NBUF *)nbuf->node.next; - } - } - - set_ipl(level); -#endif -} +/* + * File: nbuf.c + * Purpose: Implementation of network buffer scheme. + * + * Notes: + */ +#include "queue.h" +#include "net.h" +#include "driver_mem.h" +#include "exceptions.h" +#include "bas_types.h" +#include "bas_printf.h" +/* + * Queues used for network buffer storage + */ +QUEUE nbuf_queue[NBUF_MAXQ]; + +/* + * Some devices require line-aligned buffers. In order to accomplish + * this, the nbuf data is over-allocated and adjusted. The following + * array keeps track of the original data pointer returned by malloc + */ +uint8_t *unaligned_buffers[NBUF_MAX]; + +/* + * Initialize all the network buffer queues + * + * Return Value: + * 0 success + * 1 failure + */ +int nbuf_init(void) +{ + int i; + NBUF *nbuf; + + for (i=0; idata = (uint8_t *)((uint32_t)(unaligned_buffers[i] + 15) & 0xFFFFFFF0); + if (!nbuf->data) + { + return 1; + } + + /* Initialize the network buffer */ + nbuf->offset = 0; + nbuf->length = 0; + + /* Add the network buffer to the free list */ + queue_add(&nbuf_queue[NBUF_FREE], (QNODE *)nbuf); + } + + xprintf("NBUF allocation complete\n"); + + return 0; +} + +/* + * Return all the allocated memory to the heap + */ +void nbuf_flush(void) +{ + NBUF *nbuf; + int i, level = set_ipl(7); + int n = 0; + + for (i = 0; i < NBUF_MAX; ++i) + driver_mem_free((uint8_t *) unaligned_buffers[i]); + + for (i = 0; i < NBUF_MAXQ; ++i) + { + while ((nbuf = (NBUF *) queue_remove(&nbuf_queue[i])) != NULL) + { + driver_mem_free(nbuf); + ++n; + } + } + set_ipl(level); +} + +/* + * Allocate a network buffer from the free list + * + * Return Value: + * Pointer to a free network buffer + * NULL if none are available + */ +NBUF *nbuf_alloc(void) +{ + NBUF *nbuf; + int level = set_ipl(7); + + nbuf = (NBUF *) queue_remove(&nbuf_queue[NBUF_FREE]); + set_ipl(level); + + return nbuf; +} + +/* + * Add the specified network buffer back to the free list + * + * Parameters: + * nbuf Buffer to add back to the free list + */ +void nbuf_free(NBUF *nbuf) +{ + int level = set_ipl(7); + + nbuf->offset = 0; + nbuf->length = NBUF_SZ; + queue_add(&nbuf_queue[NBUF_FREE],(QNODE *)nbuf); + + set_ipl(level); +} + +/* + * Remove a network buffer from the specified queue + * + * Parameters: + * q The index that identifies the queue to pull the buffer from + */ +NBUF *nbuf_remove(int q) +{ + NBUF *nbuf; + int level = set_ipl(7); + + nbuf = (NBUF *) queue_remove(&nbuf_queue[q]); + set_ipl(level); + + return nbuf; +} + +/* + * Add a network buffer to the specified queue + * + * Parameters: + * q The index that identifies the queue to add the buffer to + */ +void nbuf_add(int q, NBUF *nbuf) +{ + int level = set_ipl(7); + queue_add(&nbuf_queue[q],(QNODE *)nbuf); + set_ipl(level); +} + +/* + * Put all the network buffers back into the free list + */ +void nbuf_reset(void) +{ + NBUF *nbuf; + int i, level = set_ipl(7); + + for (i = 1; i < NBUF_MAXQ; ++i) + { + while ((nbuf = nbuf_remove(i)) != NULL) + nbuf_free(nbuf); + } + set_ipl(level); +} + +/* + * Display all the nbuf queues + */ +void nbuf_debug_dump(void) +{ +#ifdef DEBUG + NBUF *nbuf; + int i, j, level; + + level = set_ipl(7); + + for (i = 0; i < NBUF_MAXQ; ++i) + { + printf("\n\nQueue #%d\n\n",i); + printf("\tBuffer Location\tOffset\tLength\n"); + printf("--------------------------------------\n"); + j = 0; + nbuf = (NBUF *)queue_peek(&nbuf_queue[i]); + while (nbuf != NULL) + { + printf("%d\t 0x%08x\t0x%04x\t0x%04x\n",j++,nbuf->data, + nbuf->offset, + nbuf->length); + nbuf = (NBUF *)nbuf->node.next; + } + } + + set_ipl(level); +#endif +} diff --git a/BaS_gcc/net/nif.c b/BaS_gcc/net/nif.c index a1776c5..a2d6194 100644 --- a/BaS_gcc/net/nif.c +++ b/BaS_gcc/net/nif.c @@ -14,105 +14,105 @@ int nif_protocol_exist(NIF *nif, uint16_t protocol) { - /* - * This function searches the list of supported protocols - * on the particular NIF and if a protocol handler exists, - * true is returned. This function is useful for network cards - * that needn't read in the entire frame but can discard frames - * arbitrarily. - */ - int index; + /* + * This function searches the list of supported protocols + * on the particular NIF and if a protocol handler exists, + * true is returned. This function is useful for network cards + * that needn't read in the entire frame but can discard frames + * arbitrarily. + */ + int index; - for (index = 0; index < nif->num_protocol; ++index) - { - if (nif->protocol[index].protocol == protocol) - { - return true; - } - } - return false; + for (index = 0; index < nif->num_protocol; ++index) + { + if (nif->protocol[index].protocol == protocol) + { + return true; + } + } + return false; } void nif_protocol_handler(NIF *nif, uint16_t protocol, NBUF *pNbuf) { - /* - * This function searches the list of supported protocols - * on the particular NIF and if a protocol handler exists, - * the protocol handler is invoked. This routine called by - * network device driver after receiving a frame. - */ - int index; + /* + * This function searches the list of supported protocols + * on the particular NIF and if a protocol handler exists, + * the protocol handler is invoked. This routine called by + * network device driver after receiving a frame. + */ + int index; - for (index = 0; index < nif->num_protocol; ++index) - { - if (nif->protocol[index].protocol == protocol) - nif->protocol[index].handler(nif,pNbuf); - } + for (index = 0; index < nif->num_protocol; ++index) + { + if (nif->protocol[index].protocol == protocol) + nif->protocol[index].handler(nif,pNbuf); + } } void *nif_get_protocol_info (NIF *nif, uint16_t protocol) { - /* - * This function searches the list of supported protocols - * on the particular NIF and returns a pointer to the - * config info for 'protocol', otherwise NULL is returned. - */ - int index; + /* + * This function searches the list of supported protocols + * on the particular NIF and returns a pointer to the + * config info for 'protocol', otherwise NULL is returned. + */ + int index; - for (index = 0; index < nif->num_protocol; ++index) - { - if (nif->protocol[index].protocol == protocol) - return (void *)nif->protocol[index].info; - } - return (void *)0; + for (index = 0; index < nif->num_protocol; ++index) + { + if (nif->protocol[index].protocol == protocol) + return (void *)nif->protocol[index].info; + } + return (void *)0; } int nif_bind_protocol (NIF *nif, uint16_t protocol, - void (*handler)(NIF *,NBUF *), - void *info) + void (*handler)(NIF *,NBUF *), + void *info) { - /* - * This function registers 'protocol' as a supported - * protocol in 'nif'. - */ - if (nif->num_protocol < (MAX_SUP_PROTO - 1)) - { - nif->protocol[nif->num_protocol].protocol = protocol; - nif->protocol[nif->num_protocol].handler = (void(*)(NIF*,NBUF*))handler; - nif->protocol[nif->num_protocol].info = info; - ++nif->num_protocol; - return true; - } - return false; + /* + * This function registers 'protocol' as a supported + * protocol in 'nif'. + */ + if (nif->num_protocol < (MAX_SUP_PROTO - 1)) + { + nif->protocol[nif->num_protocol].protocol = protocol; + nif->protocol[nif->num_protocol].handler = (void(*)(NIF*,NBUF*))handler; + nif->protocol[nif->num_protocol].info = info; + ++nif->num_protocol; + return true; + } + return false; } NIF *nif_init (NIF *nif) { - int i; + int i; - for (i = 0; i < ETH_ADDR_LEN; ++i) - { - nif->hwa[i] = 0; - nif->broadcast[i] = 0xFF; - } + for (i = 0; i < ETH_ADDR_LEN; ++i) + { + nif->hwa[i] = 0; + nif->broadcast[i] = 0xFF; + } - for (i = 0; i < MAX_SUP_PROTO; ++i) - { - nif->protocol[i].protocol = 0; - nif->protocol[i].handler = 0; - nif->protocol[i].info = 0; - } - nif->num_protocol = 0; + for (i = 0; i < MAX_SUP_PROTO; ++i) + { + nif->protocol[i].protocol = 0; + nif->protocol[i].handler = 0; + nif->protocol[i].info = 0; + } + nif->num_protocol = 0; - nif->mtu = 0; - nif->ch = 0; - nif->send = 0; + nif->mtu = 0; + nif->ch = 0; + nif->send = 0; - nif->f_rx = 0; - nif->f_tx = 0; - nif->f_rx_err = 0; - nif->f_tx_err = 0; - nif->f_err = 0; + nif->f_rx = 0; + nif->f_tx = 0; + nif->f_rx_err = 0; + nif->f_tx_err = 0; + nif->f_err = 0; - return nif; + return nif; } diff --git a/BaS_gcc/sys/BaS.c b/BaS_gcc/sys/BaS.c index 2bd3cbf..26da3ea 100644 --- a/BaS_gcc/sys/BaS.c +++ b/BaS_gcc/sys/BaS.c @@ -42,6 +42,7 @@ #include "eth.h" #include "nbuf.h" #include "nif.h" +#include "fec.h" /* imported routines */ extern int mmu_init(); @@ -366,6 +367,19 @@ void BaS(void) xprintf("BaS initialization finished, enable interrupts\r\n"); enable_coldfire_interrupts(); + nbuf_init(); + uint8_t mac[6] = {0x00, 0x04, 0x9f, 0x01, 0x01, 0x01}; /* this is a Freescale MAC address */ + uint8_t bc[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; /* this is a Freescale MAC address */ + fec_eth_setup(0, FEC_MODE_MII, FEC_MII_100BASE_TX, FEC_MII_FULL_DUPLEX, mac); + nif_init(&nif1); + nif1.mtu = ETH_MTU; + nif1.send = fec0_send; + memcpy(nif1.hwa, mac, 6); + memcpy(nif1.broadcast, bc, 6); + bootp_request(&nif1, 0); + + + xprintf("call EmuTOS\r\n"); ROM_HEADER* os_header = (ROM_HEADER*)TOS; os_header->initial_pc(); diff --git a/BaS_gcc/sys/driver_mem.c b/BaS_gcc/sys/driver_mem.c index 48cfe73..0750e14 100644 --- a/BaS_gcc/sys/driver_mem.c +++ b/BaS_gcc/sys/driver_mem.c @@ -307,7 +307,7 @@ static int init_count = 0; int driver_mem_init(void) { - if (! init_count == 0) + if (init_count == 0) { #ifdef USE_RADEON_MEMORY driver_mem_buffer = (void *) offscreen_reserved(); diff --git a/BaS_gcc/sys/sysinit.c b/BaS_gcc/sys/sysinit.c index 4cdc6ba..1ff348f 100644 --- a/BaS_gcc/sys/sysinit.c +++ b/BaS_gcc/sys/sysinit.c @@ -48,6 +48,7 @@ #include "dma.h" #include "mod_devicetable.h" #include "pci_ids.h" +#include "driver_mem.h" #include "usb.h" #define UNUSED(x) (void)(x) /* Unused variable */ @@ -1126,6 +1127,7 @@ void initialize_hardware(void) } #endif /* MACHINE_FIREBEE */ + driver_mem_init(); init_pci(); /* do not try to init USB for now on the Firebee, it hangs the machine */ diff --git a/BaS_gcc/usb/usb_mem.c b/BaS_gcc/usb/usb_mem.c deleted file mode 100644 index cc7364b..0000000 --- a/BaS_gcc/usb/usb_mem.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * driver_mem.c - * - * based from Emutos / BDOS - * - * Copyright (c) 2001 Lineo, Inc. - * - * Authors: Karl T. Braun, Martin Doering, Laurent Vogel - * - * This file is distributed under the GPL, version 2 or at your - * option any later version. - */ - -#include -#include "bas_string.h" -#include "bas_printf.h" -#include "usb.h" -#include "exceptions.h" /* set_ipl() */ - -#if MACHINE_FIREBEE -#include "firebee.h" -#elif MACHINE_M5484LITE -#include "m5484l.h" -#endif - -#ifndef FALSE -#define FALSE 0 -#endif -#ifndef TRUE -#define TRUE 1 -#endif - -#undef DRIVER_MEM_DEBUG - -#ifdef DRIVER_MEM_DEBUG -#define dbg(fmt, args...) xprintf(fmt, ##args) -#else -#define dbg(fmt, args...) -#endif - -extern void *info_fvdi; -extern long offscren_reserved(void); - -extern uint8_t driver_mem[DRIVER_MEM_SIZE]; /* defined in linker control file */ - -/* MD - Memory Descriptor */ - -#define MD struct _md_ - -MD -{ - MD *m_link; - long m_start; - long m_length; - void *m_own; -}; - -/* MPB - Memory Partition Block */ - -#define MPB struct _mpb - -MPB -{ - MD *mp_mfl; - MD *mp_mal; - MD *mp_rover; -}; - -#define MAXMD 256 - -static MD tab_md[MAXMD]; -static MPB pmd; - -static void *xmgetblk(void) -{ - int i; - - for (i = 0; i < MAXMD; i++) - { - if (tab_md[i].m_own == NULL) - { - tab_md[i].m_own = (void*)1L; - return(&tab_md[i]); - } - } - return NULL; -} - -static void xmfreblk(void *m) -{ - int i = (int)(((long) m - (long) tab_md) / sizeof(MD)); - if ((i > 0) && (i < MAXMD)) - { - tab_md[i].m_own = NULL; - } -} - -static MD *ffit(long amount, MPB *mp) -{ - MD *p, *q, *p1; /* free list is composed of MD's */ - int maxflg; - long maxval; - - if (amount != -1) - { - amount += 15; /* 16 bytes alignment */ - amount &= 0xFFFFFFF0; - } - - if ((q = mp->mp_rover) == 0) /* get rotating pointer */ - { - return 0; - } - - maxval = 0; - maxflg = ((amount == -1) ? TRUE : FALSE) ; - p = q->m_link; /* start with next MD */ - do /* search the list for an MD with enough space */ - { - if (p == 0) - { - /* at end of list, wrap back to start */ - q = (MD *) &mp->mp_mfl; /* q => mfl field */ - p = q->m_link; /* p => 1st MD */ - } - if ((!maxflg) && (p->m_length >= amount)) - { - /* big enough */ - if (p->m_length == amount) - { - q->m_link = p->m_link; /* take the whole thing */ - } - else - { - /* - * break it up - 1st allocate a new - * MD to describe the remainder - */ - p1 = xmgetblk(); - if (p1 == NULL) - { - return(NULL); - } - - /* init new MD */ - p1->m_length = p->m_length - amount; - p1->m_start = p->m_start + amount; - p1->m_link = p->m_link; - p->m_length = amount; /* adjust allocated block */ - q->m_link = p1; - } - /* link allocate block into allocated list, - mark owner of block, & adjust rover */ - p->m_link = mp->mp_mal; - mp->mp_mal = p; - mp->mp_rover = (q == (MD *) &mp->mp_mfl ? q->m_link : q); - return(p); /* got some */ - } - else if (p->m_length > maxval) - maxval = p->m_length; - p = ( q=p )->m_link; - } while(q != mp->mp_rover); - - /* - * return either the max, or 0 (error) - */ - if (maxflg) - { - maxval -= 15; /* 16 bytes alignment */ - if (maxval < 0) - { - maxval = 0; - } - else - { - maxval &= 0xFFFFFFF0; - } - } - return(maxflg ? (MD *) maxval : 0); -} - -static void freeit(MD *m, MPB *mp) -{ - MD *p, *q; - - q = 0; - for (p = mp->mp_mfl; p ; p = (q = p) -> m_link) - { - if (m->m_start <= p->m_start) - { - break; - } - } - m->m_link = p; - - if (q) - { - q->m_link = m; - } - else - { - mp->mp_mfl = m; - } - - if (!mp->mp_rover) - { - mp->mp_rover = m; - } - - if (p) - { - if (m->m_start + m->m_length == p->m_start) - { - /* join to higher neighbor */ - m->m_length += p->m_length; - m->m_link = p->m_link; - if (p == mp->mp_rover) - { - mp->mp_rover = m; - } - xmfreblk(p); - } - } - if (q) - { - if (q->m_start + q->m_length == m->m_start) - { - /* join to lower neighbor */ - q->m_length += m->m_length; - q->m_link = m->m_link; - if (m == mp->mp_rover) - { - mp->mp_rover = q; - } - xmfreblk(m); - } - } -} - -int driver_mem_free(void *addr) -{ - int level; - MD *p, **q; - MPB *mpb; - mpb = &pmd; - level = set_ipl(7); - - for(p = *(q = &mpb->mp_mal); p; p = *(q = &p->m_link)) - { - if ((long) addr == p->m_start) - { - break; - } - } - - if (!p) - { - set_ipl(level); - return(-1); - } - - *q = p->m_link; - freeit(p, mpb); - set_ipl(level); - - dbg("driver_mem_free(0x%08X)\r\n", addr); - - return(0); -} - -void *driver_mem_alloc(long amount) -{ - void *ret = NULL; - int level; - MD *m; - - if (amount == -1L) - { - return((void *)ffit(-1L, &pmd)); - } - - if (amount <= 0 ) - { - return(0); - } - - if ((amount & 1)) - { - amount++; - } - - level = set_ipl(7); - m = ffit(amount, &pmd); - - if (m != NULL) - { - ret = (void *)m->m_start; - } - set_ipl(level); - dbg("driver_mem_alloc(%d) = 0x%08X\r\n", amount, ret); - - return(ret); -} - - - -int usb_mem_init(void) -{ -#ifdef USE_RADEON_MEMORY - driver_mem_buffer = (void *) offscren_reserved(); - if (driver_mem_buffer == NULL) -#endif - memset(driver_mem_buffer, 0, DRIVER_MEM_BUFFER_SIZE); - - if (driver_mem_buffer == NULL) - { - return(-1); - } - - pmd.mp_mfl = pmd.mp_rover = &tab_md[0]; - tab_md[0].m_link = (MD *) NULL; - tab_md[0].m_start = ((long) driver_mem_buffer + 15) & ~15; - tab_md[0].m_length = DRIVER_MEM_BUFFER_SIZE; - tab_md[0].m_own = (void *) 1L; - pmd.mp_mal = (MD *) NULL; - memset(driver_mem_buffer, 0, tab_md[0].m_length); - dbg("driver memory buffer at 0x%08X size %d\r\n", tab_md[0].m_start, tab_md[0].m_length); - - return(0); -} - -void usb_mem_stop(void) -{ -#ifndef CONFIG_USB_MEM_NO_CACHE -#ifdef USE_RADEON_MEMORY - if (driver_mem_buffer == (void *) offscren_reserved()) - return; -#endif -#endif -} - - - diff --git a/BaS_gcc/util/bas_string.c b/BaS_gcc/util/bas_string.c index d622153..d39aaec 100644 --- a/BaS_gcc/util/bas_string.c +++ b/BaS_gcc/util/bas_string.c @@ -55,6 +55,19 @@ void *memset(void *s, int c, size_t n) } +int memcmp(const char *s1, const char *s2, size_t max) +{ + int i; + int cmp; + + for (i = 0; i < max; i++) + { + cmp = (*s1 - *s2); + if (cmp != 0) return cmp; + } + return cmp; +} + int strncmp(const char *s1, const char *s2, size_t max) { int i;