void set_date_ms(uint64_t date_ms) { uint64_t date = date_ms * SYS_TIMER_CLOCK_div_1000; uint32_t date_lowbits = date & (0x0000FFFF); uint32_t date_highbits = date >> 32; Set32(CLO, date_lowbits); Set32(CHI, date_highbits); }
// Convert string to bigint // Return 0 if string contains non-digit characters, else number of limbs used int ToInt(u32 *lhs, int max_limbs, const char *rhs, u32 base) { if (max_limbs < 2) return 0; lhs[0] = 0; int used = 1; char ch; while ((ch = *rhs++)) { u32 mod; if (ch >= '0' && ch <= '9') mod = ch - '0'; else mod = toupper(ch) - 'A' + 10; if (mod >= base) return 0; // lhs *= base u32 carry = Multiply32Add32(used, lhs, base, mod); // react to running out of room if (carry) { if (used >= max_limbs) return 0; lhs[used++] = carry; } } if (used < max_limbs) Set32(lhs+used, max_limbs-used, 0); return used; }
void set_next_tick_default() { uint32_t date_lowbits = Get32(CLO); date_lowbits += DEFAULT_TIMER_INTERVAL; Set32(C1, date_lowbits); }
void set_next_tick(uint32_t time_ms) { uint32_t date_lowbits = Get32(CLO); date_lowbits += (uint32_t) (time_ms * CLOCK_PATCH) ; Set32(C1, date_lowbits); }
/* Use *system timer* peripheral -> compare module CM1 */ void timer_init() { /* 10 ms seems good */ set_next_tick_default(); /* Enable timer irq */ ENABLE_TIMER_IRQ(); /* Enable interrupt *line* */ Set32(0x2000B210, 0x00000002); }
// // Permet d'envoyer des chaine de caractère. Celle-ci doit se terminer // par le caractère nul. void uart_send_str(const char *data) { if (*data == 0) { return; } do { // On attend que l'UART soit disponible while ((Get32(UART_FR) & (1u << 5u)) != 0u); // On écrit la donnée Set32(UART_DR, (unsigned int)*(data++)); } while (*data != 0); // On attend que l'UART soit disponible while ((Get32(UART_FR) & (1u << 5u)) != 0u); // Puis on envoie le caractère nul #if RPI Set32(UART_DR, 0u); #endif }
// // Initialisation void uart_init(void) { // On désactive UART Set32(UART_CR, 0u); // Initialisation GPIO (14 et 15) // On règle la fonction sur ALT0 pour les bons pins Set32(GPIO_FSEL1, Get32(GPIO_FSEL1) | (GPIO_ALT0 << GPIO_TDX0_OFF)); Set32(GPIO_FSEL1, Get32(GPIO_FSEL1) | (GPIO_ALT0 << GPIO_RDX0_OFF)); // On règle le pull down Set32(GPIO_PUD, 0u); delay(150u); Set32(GPIO_PUDCLK0, (1u << UART_TXD0_PIN) | (1u << UART_RDX0_PIN)); delay(150u); Set32(GPIO_PUD, 0u); Set32(GPIO_PUDCLK0, 0u); // On initialisation UART // On clear la line Set32(UART_LCRH, 0u); // On clear les intéruptions Set32(UART_ICR, 0u); // On règles le baud rate à 115200 baud Set32(UART_IBRD, 1u); Set32(UART_FBRD, 40u); // Line control : // - break disable // - parity disable // - stop bits disable // - fifo disabled // - word length = 8 bits Set32(UART_LCRH, (3u << 5u)); // Seuil FIFO // - On n'utilise pas la FIFO Set32(UART_IFLS, 0u); // Interruption // On masque tout Set32(UART_IMSC, (1u << 1u) | (1u << 4u) | (1u << 5u) | (1u << 6u) | (1u << 7u) | (1u << 8u) | (1u << 9u) | (1u << 10u)); // Controle : // - on active l'UART // - pas de loopback // - activation de la réception/émission // - pas de RTS // - pas de flowcontrol Set32(UART_CR, (1u << 0u) | (1u << 8u) | (1u << 9u)); }
void performFixups(PSEG s) { UINT i,j; PSEG f,t; PRELOC r; UINT offset; INT section; UINT disp; PSYMBOL pub; UINT delta; PDATABLOCK d; if(!s) return; /* recurse down tree */ for(i=0;i<s->contentCount;++i) { if(s->contentList[i].flag==SEGMENT) { performFixups(s->contentList[i].seg); } } for(i=0;i<s->relocCount;++i) { r=s->relocs+i; for(j=0;j<s->contentCount;++j) { if(s->contentList[j].flag!=DATA) continue; if((s->contentList[j].data->offset <= r->ofs) && ((s->contentList[j].data->offset + s->contentList[j].data->length) > r->ofs)) break; } if(j==s->contentCount) { addError("Fixup location %08lX is outside any data in segment %s",r->ofs,s->name); continue; } d=s->contentList[j].data; offset=r->ofs-d->offset; t=NULL; disp=0; if(r->tseg) { t=r->tseg; disp=t->base; } else if(r->text) { pub=r->text->pubdef; if(!pub) { addError("Unresolved external %s",r->text->name); continue; } t=pub->seg; if(t) disp=t->base+pub->ofs; } if(!t) { addError("Fixup target unresolved"); continue; } if(r->fseg) { f=r->fseg; } else if(r->fext) { pub=r->fext->pubdef; if(!pub) { addError("Unresolved external %s",r->fext->name); continue; } f=pub->seg; } else { f=NULL; } if(f && f->absolute && (r->base==REL_DEFAULT)) { r->base=REL_FRAME; } switch(r->base) { case REL_ABS: case REL_DEFAULT: case REL_RVA: section=t->section; while(t->parent) { t=t->parent; if(section<0) section=t->section; disp+=t->base; } if(r->base==REL_RVA) { disp-=t->base; } break; case REL_FILEPOS: if(t->absolute) { addError("Attempt to get file position of absolute segment %s",t->name); continue; } section=t->section; while(t->parent && !t->fpset) { t=t->parent; if(section<0) section=t->section; disp+=t->base; } disp-=t->base; if(t->fpset) disp+=t->filepos; if(f) { if(f->absolute) { addError("Attempt to get file position of absolute segment %s",f->name); continue; } while(f->parent && !f->fpset) { f=f->parent; if(section<0) section=f->section; disp-=f->base; } disp+=f->base; if(f->fpset) disp-=f->filepos; } break; case REL_SELF: section=t->section; while(t->parent) { t=t->parent; if(section<0) section=t->section; disp+=t->base; } f=s; disp-=r->ofs; while(f) { disp-=f->base; f=f->parent; } break; case REL_FRAME: if(!f) { addError("Unspecified frame"); continue; } while(t->parent) { t=t->parent; disp+=t->base; } section=f->section; disp-=f->base; if(section>=0) disp+=f->base&(frameAlign-1); while(f->parent && !f->absolute) { f=f->parent; if(section<0) { section=f->section; if(section>=0) disp+=f->base&(frameAlign-1); } if(section>=0) { disp-=f->base; } } break; default: addError("Unspecified reloc base"); continue; } disp+=r->disp; switch(r->rtype) { case REL_OFS8: delta=d->data[offset]; delta+=disp; d->data[offset]=delta&0xff; break; case REL_OFS16: if(disp>=0x10000) { addError("16-bit offset limit exceeded"); continue; } delta=d->data[offset]+(d->data[offset+1]<<8); delta+=disp; Set16(&d->data[offset],delta); break; case REL_OFS32: delta=d->data[offset]+(d->data[offset+1]<<8)+(d->data[offset+2]<<16)+(d->data[offset+3]<<24); delta+=disp; Set32(&d->data[offset],delta); break; case REL_BYTE2: delta=d->data[offset]; delta+=disp>>8; d->data[offset]=delta&0xff; break; case REL_SEG: if(section<0) { addError("Segmented reloc not permitted for specified frame"); continue; } if(section>=0x10000) { addError("Section number too large %08lX",section); continue; } delta=d->data[offset]+(d->data[offset+1]<<8); delta+=section; Set16(&d->data[offset],delta); break; case REL_PTR16: if(section<0) { addError("Segmented reloc not permitted for specified frame"); continue; } if(section>=0x10000) { addError("Section number too large %08lX",section); continue; } if(disp>=0x10000) { addError("16-bit offset limit exceeded"); continue; } delta=d->data[offset]+(d->data[offset+1]<<8); delta+=disp; Set16(&d->data[offset],delta); delta=d->data[offset+2]+(d->data[offset+3]<<8); delta+=section; Set16(&d->data[offset+2],delta); break; case REL_PTR32: if(section<0) { addError("Segmented reloc not permitted for specified frame"); continue; } delta=d->data[offset]+(d->data[offset+1]<<8)+(d->data[offset+2]<<16)+(d->data[offset+3]<<24); delta+=disp; Set32(&d->data[offset],delta); delta=d->data[offset+4]+(d->data[offset+5]<<8); delta+=section; Set16(&d->data[offset+4],delta); break; default: addError("Invalid relocation type"); continue; break; } } }