2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
7 #include <proto/exec.h>
9 #include <proto/alib.h>
12 #include <dos/exall.h>
13 #include <dos/rdargs.h>
15 #include <exec/memory.h>
16 #include <exec/types.h>
17 #include <exec/lists.h>
18 #include <devices/serial.h>
20 #include <aros/macros.h>
25 #define PARAM "FILE/A,UNIT=UNITNUM/K/N,START/S"
26 #define ARG_FILENAME 0
31 #define BAUDRATE 57600
33 int start_protocol(struct IOExtSer
*, ULONG
, char * );
37 void free_packet(struct Packet
* packet
);
38 void free_all_packets(void);
40 struct List PacketList
;
41 struct List PilotMemList
;
46 IPTR
* args
[TOTAL_ARGS
] = {NULL
, NULL
};
48 int baudrate
= BAUDRATE
;
49 struct IOExtSer
* IORequest
;
51 struct MsgPort
* SerPort
;
53 struct Interrupt SerInterrupt
;
56 NEWLIST(&PilotMemList
);
58 rda
= ReadArgs(PARAM
, (IPTR
*)args
, NULL
);
60 if (NULL
!= args
[ARG_UNITNUM
])
61 unitnum
= *args
[ARG_UNITNUM
];
63 printf("Opening serial port unit %d with %d baud.\n",
67 SerPort
= CreatePort("serial port message port",0);
68 IORequest
= (struct IOExtSer
*)CreateExtIO(SerPort
, sizeof(struct IOExtSer
));
70 err
= OpenDevice("serial.device",unitnum
,(struct IORequest
*)IORequest
,flags
);
74 * Try to set the baudrate.
76 IORequest
->IOSer
.io_Command
= SDCMD_SETPARAMS
;
77 IORequest
->io_Baud
= baudrate
;
78 // DoIO((struct IORequest *)IORequest);
79 if (0 == ((struct IORequest
*)IORequest
)->io_Error
) {
81 * serial device is opened.
86 err
= start_protocol(IORequest
, args
[ARG_START
], args
[ARG_FILENAME
]);
88 printf("Could not set baudrate!\n");
91 CloseDevice((struct IORequest
*)IORequest
);
93 printf("Could not open serial device unit %d.\n",unitnum
);
95 DeleteExtIO((struct IORequest
*)IORequest
);
98 printf("Forgot to give a mandator argument?\n");
104 #define TYPE_HANDSHAKE 0x01
105 #define TYPE_READ_MEM 0x02
106 #define TYPE_WRITE_MEM 0x03
107 #define TYPE_MEM_CONTENT 0x04
108 #define TYPE_WRITE_MEM_ACK 0x05
109 #define TYPE_GET_SPECIAL_INFO 0x06
110 #define TYPE_START_PROGRAM 0x07
111 #define TYPE_START_PROGRAM_ACK 0x08
112 #define TYPE_QUIT 0x10
116 struct Node next_packet
;
117 UWORD payload_length
;
125 GET_FRAME_BEGINNING
= 0x01,
126 GET_PAYLOAD_LENGTH_HI
,
127 GET_PAYLOAD_LENGTH_LO
,
133 void free_packet(struct Packet
* packet
)
136 FreeMem(packet
->payload
,packet
->payload_length
);
137 FreeMem(packet
, sizeof(struct Packet
));
140 struct Packet
* current_packet
;
142 void free_all_packets(void)
145 if (NULL
!= current_packet
) {
146 free_packet(current_packet
);
149 while (NULL
!= (p
= (struct Packet
*)RemHead(&PacketList
)))
153 struct Packet
* get_next_packet(struct IOExtSer
* IORequest
)
155 struct Packet
* p
= NULL
;
157 IORequest
->IOSer
.io_Command
= SDCMD_QUERY
;
158 DoIO((struct IORequest
*)IORequest
);
160 if (0 != (len
= IORequest
->IOSer
.io_Actual
)) {
163 // printf("Reading %ld bytes from serial port.\n",
164 // IORequest->IOSer.io_Actual);
166 buf
= AllocMem(len
, MEMF_ANY
);
169 IORequest
->IOSer
.io_Command
= CMD_READ
;
170 IORequest
->IOSer
.io_Flags
= IOF_QUICK
;
171 IORequest
->IOSer
.io_Length
= len
;
172 IORequest
->IOSer
.io_Data
= buf
;
174 DoIO((struct IORequest
*)IORequest
);
180 if (NULL
== current_packet
) {
181 current_packet
= AllocMem(sizeof(struct Packet
),
183 current_packet
->state
= GET_FRAME_BEGINNING
;
186 switch (current_packet
->state
) {
187 case GET_FRAME_BEGINNING
:
189 current_packet
->state
= GET_PAYLOAD_LENGTH_HI
;
191 printf("Could not find beginning of frame. Dropping byte (x%02x)!\n",
196 case GET_PAYLOAD_LENGTH_HI
:
197 current_packet
->payload_length
= ((UWORD
)buf
[i
]) << 8;
198 current_packet
->state
= GET_PAYLOAD_LENGTH_LO
;
202 case GET_PAYLOAD_LENGTH_LO
:
203 current_packet
->payload_length
|= ((UWORD
)buf
[i
]);
204 current_packet
->state
= GET_TYPE
;
205 current_packet
->payload
= AllocMem(current_packet
->payload_length
, MEMF_ANY
);
207 //printf("Reading packet with length %d\n",current_packet->payload_length);
211 current_packet
->payload_type
= buf
[i
];
212 current_packet
->state
= GET_PAYLOAD
;
218 current_packet
->pos
< current_packet
->payload_length
) {
219 if (0x7f == buf
[i
]) {
221 * Must not appear here!
223 //printf("Received faulty packet (x%02x). Dropping it.\n",buf[i]);
224 free_packet(current_packet
);
225 current_packet
= NULL
;
228 current_packet
->payload
[current_packet
->pos
++] = buf
[i
];
230 //printf("%c\n",buf[i]);
233 if (current_packet
->pos
== current_packet
->payload_length
)
234 current_packet
->state
= GET_FRAME_END
;
238 if (0x7f == buf
[i
]) {
240 ¤t_packet
->next_packet
);
241 //printf("Got a complete packet!\n");
243 //printf("Received faulty packet (x%02x). Dropping it.\n",buf[i]);
244 free_packet(current_packet
);
245 current_packet
= NULL
;
248 current_packet
= NULL
;
259 * Try to get the first complete packet in the list.
261 p
= (struct Packet
*)RemHead(&PacketList
);
266 //printf("Will return a packet!\n");
268 * Reconvert the payload (if necessary)
270 while (i
< p
->payload_length
) {
271 if (0x27 == p
->payload
[i
])
278 * Un-convert the payload
280 char * pl
= AllocMem(p
->payload_length
- c
, MEMF_ANY
);
281 printf("Unconverting payload!\n");
285 while (i
< p
->payload_length
) {
286 if (0x27 == p
->payload
[i
]) {
287 if (0x28 == p
->payload
[i
+1]) {
293 pl
[_i
] = p
->payload
[i
];
299 FreeMem(p
->payload
, p
->payload_length
);
301 p
->payload_length
-= c
;
309 void send_packet(struct IOExtSer
* IORequest
, char * buffer
, UWORD len
, UBYTE type
)
315 * Count number of characters to escape.
317 if (0x7f == buffer
[i
] || 0x27 == buffer
[i
])
322 packet
= AllocMem(1 + /* frame begin */
323 2 + /* length of payload indicator */
325 len
+ c
+ /* payload */
329 if (NULL
!= packet
) {
332 packet
[1] = ((len
+c
) >> 8) & 0xff;
333 packet
[2] = ((len
+c
) ) & 0xff;
338 * convert forbidden bytes.
341 if (0x7f == buffer
[i
]) {
342 packet
[pos
++] = 0x27;
343 packet
[pos
] = 0x29; /* = 0x7f */
344 printf("Converting packet to send!\n");
345 } else if (0x27 == buffer
[i
]) {
346 packet
[pos
++] = 0x27;
347 packet
[pos
] = 0x28; /* = 0x27 */
348 printf("Converting packet to send!\n");
350 packet
[pos
] = buffer
[i
];
356 * End marker for the packet.
363 IORequest
->IOSer
.io_Command
= CMD_WRITE
;
364 IORequest
->IOSer
.io_Flags
= 0;
365 IORequest
->IOSer
.io_Length
= pos
+1;
366 IORequest
->IOSer
.io_Data
= packet
;
368 DoIO((struct IORequest
*)IORequest
);
369 FreeMem(packet
, pos
+1);
375 * Do a handshake. Other side sends "AROS?", I send back "AROS!" and get back
378 int do_handshake(struct IOExtSer
* IORequest
)
380 struct Packet
* packet
;
385 packet
= get_next_packet(IORequest
);
386 if (NULL
!= packet
) {
387 if (0 == strncmp("AROS?",&packet
->payload
[0],5) &&
388 5 == packet
->payload_length
) {
389 printf("Got 'AROS?' Sending 'AROS!'\n");
391 send_packet(IORequest
,"AROS!",5, TYPE_HANDSHAKE
);
395 printf("Wrong payload: %s\n",packet
->payload
);
403 if (FALSE
== found
) {
411 packet
= get_next_packet(IORequest
);
412 if (NULL
!= packet
) {
413 if (0 == strncmp("greets!",&packet
->payload
[0],7) &&
414 7 == packet
->payload_length
) {
416 printf("\t\tHandshake complete!!\n");
420 //printf("2. Wrong payload: %s\n",packet->payload);
425 //printf("Could not get any packet at all!\n");
440 } /* __attribute__((packed)) */;
442 char * read_mem(struct IOExtSer
* IORequest
, ULONG addr
, UWORD num_bytes
)
448 _rm
.num_bytes
= AROS_WORD2BE(num_bytes
);
449 _rm
.addr
= AROS_LONG2BE(addr
);
452 printf("Sending request for memory content!\n");
456 struct Packet
* packet
;
458 send_packet(IORequest
, (char *)&_rm
, 6, TYPE_READ_MEM
);
464 packet
= get_next_packet(IORequest
);
465 if (NULL
!= packet
) {
466 if (TYPE_MEM_CONTENT
== packet
->payload_type
&&
467 0 == memcmp(&_rm
.addr
,&packet
->payload
[0],sizeof(addr
)) &&
468 packet
->payload_length
== sizeof(addr
) + num_bytes
) {
472 while (i
< packet
->payload_length
) {
473 printf("x%02x ",(UBYTE
)packet
->payload
[i
]);
480 buf
= AllocMem(packet
->payload_length
-4,MEMF_ANY
);
482 memcpy(buf
, &packet
->payload
[4], packet
->payload_length
-4);
487 //printf("%s: Wrong packet.\n",__FUNCTION__);
494 //printf("Could not get any packet at all!\n");
502 int write_mem(struct IOExtSer
* IORequest
, ULONG addr
, char * buf
, UWORD num_bytes
)
506 char * _buf
= AllocMem(num_bytes
+ sizeof(addr
), MEMF_ANY
);
507 ULONG _addr
= AROS_BE2LONG(addr
);
511 memcpy(_buf
, &_addr
, sizeof(addr
));
512 memcpy(_buf
+sizeof(addr
), buf
, num_bytes
);
514 struct Packet
* packet
;
516 send_packet(IORequest
, _buf
, num_bytes
+sizeof(addr
), TYPE_WRITE_MEM
);
522 packet
= get_next_packet(IORequest
);
523 if (NULL
!= packet
) {
524 if (TYPE_WRITE_MEM_ACK
== packet
->payload_type
&&
525 0 == memcmp(&_addr
,&packet
->payload
[0],sizeof(addr
))) {
526 printf("\tSuccessfully wrote %d bytes starting at address 0x%x\n",num_bytes
,addr
);
528 FreeMem(_buf
, num_bytes
+ sizeof(addr
));
531 //printf("%s: Wrong packet.\n",__FUNCTION__);
538 //printf("Could not get any packet at all!\n");
543 FreeMem(_buf
, num_bytes
+ sizeof(addr
));
547 int send_chunk(struct IOExtSer
* IORequest
, ULONG addr
, char * buf
, UWORD num_bytes
)
549 printf("Sending chunk of size %d to address %x\n",num_bytes
,addr
);
550 while (num_bytes
> 0) {
552 if (num_bytes
< send
)
554 if (write_mem(IORequest
, addr
, buf
, send
) < 0) {
555 printf("send_chunk failed!\n");
561 printf("%d more bytes.\n",num_bytes
);
566 int start_program(struct IOExtSer
* IORequest
, ULONG addr
)
570 ULONG _addr
= AROS_BE2LONG(addr
);
572 printf("Sending request to start program at address 0x%x!\n",addr
);
575 struct Packet
* packet
;
577 send_packet(IORequest
, (char *)&_addr
, sizeof(_addr
), TYPE_START_PROGRAM
);
583 packet
= get_next_packet(IORequest
);
584 if (NULL
!= packet
) {
585 if (TYPE_START_PROGRAM_ACK
== packet
->payload_type
) {
586 printf("Sucessfully started program!\n");
590 //printf("%s: Wrong packet.\n",__FUNCTION__);
597 //printf("Could not get any packet at all!\n");
613 int get_special_info(struct IOExtSer
* IORequest
, struct special_info
* si
)
618 printf("Sending request for special info!\n");
621 struct Packet
* packet
;
623 send_packet(IORequest
, (char *)&ctr
, 1, TYPE_GET_SPECIAL_INFO
);
629 packet
= get_next_packet(IORequest
);
630 if (NULL
!= packet
) {
631 if (TYPE_GET_SPECIAL_INFO
== packet
->payload_type
&&
632 packet
->payload_length
== sizeof(struct special_info
)) {
633 memcpy(si
, packet
->payload
, packet
->payload_length
);
635 printf("\t\tGot special info!\n");
638 //printf("%s: Wrong packet. (%d)\n",__FUNCTION__,packet->payload_type);
639 //printf("%d-%d\n",packet->payload_length,sizeof(struct special_info));
646 //printf("Could not get any packet at all!\n");
663 UWORD GRPBASEA
; /* 0xfffff100 */
664 UWORD GRPBASEB
; /* 0xfffff102 */
665 UWORD GRPBASEC
; /* 0xfffff104 */
666 UWORD GRPBASED
; /* 0xfffff106 */
668 UWORD GRPMASKA
; /* 0xfffff108 */
669 UWORD GRPMASKB
; /* 0xfffff10a */
670 UWORD GRPMASKC
; /* 0xfffff10c */
671 UWORD GRPMASKD
; /* 0xfffff10e */
673 ULONG CSA0
; /* 0xfffff110 */
674 ULONG CSA1
; /* 0xfffff114 */
675 ULONG CSA2
; /* 0xfffff118 */
676 ULONG CSA3
; /* 0xfffff11c */
678 ULONG empty1
; /* 0xfffff120 */
679 ULONG empty2
; /* 0xfffff124 */
680 ULONG empty3
; /* 0xfffff128 */
681 ULONG empty4
; /* 0xfffff12c */
683 ULONG CSC0
; /* 0xfffff130 */
684 ULONG CSC1
; /* 0xfffff134 */
685 ULONG CSC2
; /* 0xfffff138 */
686 ULONG CSC3
; /* 0xfffff13c */
690 struct special_info SI
;
691 } __attribute__((packed
)) Regs
;
694 * This function builds the current palm memory layout into a linked
695 * list of simple structures. Later on the relocator will look at this
696 * list and try to grab a chunk.
698 void BuildPilotMem(struct registers
* reg
)
702 pm
= AllocMem(sizeof(struct PilotMem
),MEMF_CLEAR
);
703 #warning Should really build a much better list here!!!
704 pm
->start
= (AROS_LONG2BE(reg
->SI
.end
) & 0xffff0000) + 0x4000;
705 pm
->end
= pm
->start
+0x100000;
706 AddTail(&PilotMemList
, &pm
->node
);
709 void * GetPilotMem(ULONG size
)
711 struct PilotMem
* pm
;
713 /* For alignment purposes add 4 to the size */
715 printf("%s: Trying to allocate %ld bytes on palm!\n",__FUNCTION__
,size
);
716 ForeachNode(&PilotMemList
, pm
) {
717 if (pm
->end
- pm
->start
+ 1 >= size
) {
719 if (0 == (pm
->start
& 0x03))
722 ret
= (void *)((pm
->start
& 0xfffffffc) + 4);
723 printf("Found a memory chunk at 0x%x\n",ret
);
727 pm
= (struct PilotMem
*)pm
->node
.ln_Succ
;
732 #include "myinternalloadseg_elf.c"
734 int upload_program(struct IOExtSer
* IORequest
, char * name
, ULONG
* startaddr
)
737 BPTR file
= Open(name
, MODE_OLDFILE
);
741 printf("Opened file!\n");
742 segs
= MyInternalLoadSeg_ELF(file
, NULL
, NULL
, IORequest
, startaddr
);
746 printf("Could not open file %s\n",name
);
753 int start_protocol(struct IOExtSer
* IORequest
, ULONG start
, char * filename
)
759 err
= do_handshake(IORequest
);
761 printf("Handshake failed!\n");
765 buf
= read_mem(IORequest
,0xfffff100,0x40);
767 memcpy(&Regs
, buf
, 0x40);
771 buf
= read_mem(IORequest
,0xfffffA00,0x4);
773 memcpy(&Regs
.LSSA
, buf
, 0x4);
777 err
= get_special_info(IORequest
,&Regs
.SI
);
779 printf("start: %lx\n",AROS_LONG2BE(Regs
.SI
.start
));
780 printf("end: %lx\n",AROS_LONG2BE(Regs
.SI
.end
));
781 printf("ssp: %lx\n",AROS_LONG2BE(Regs
.SI
.ssp
));
783 printf("GRPBASEA : %x\n",AROS_WORD2BE(Regs
.GRPBASEA
));
784 printf("GRPBASEB : %x\n",AROS_WORD2BE(Regs
.GRPBASEB
));
785 printf("GRPBASEC : %x\n",AROS_WORD2BE(Regs
.GRPBASEC
));
786 printf("GRPBASED : %x\n",AROS_WORD2BE(Regs
.GRPBASED
));
788 printf("GRPMASKA : %x\n",AROS_WORD2BE(Regs
.GRPMASKA
));
789 printf("GRPMASKB : %x\n",AROS_WORD2BE(Regs
.GRPMASKB
));
790 printf("GRPMASKC : %x\n",AROS_WORD2BE(Regs
.GRPMASKC
));
791 printf("GRPMASKD : %x\n",AROS_WORD2BE(Regs
.GRPMASKD
));
793 printf("CSA0 : %lx\n",AROS_LONG2BE(Regs
.CSA0
));
794 printf("CSA1 : %lx\n",AROS_LONG2BE(Regs
.CSA1
));
795 printf("CSA2 : %lx\n",AROS_LONG2BE(Regs
.CSA2
));
796 printf("CSA3 : %lx\n",AROS_LONG2BE(Regs
.CSA3
));
798 printf("CSC0 : %lx\n",AROS_LONG2BE(Regs
.CSC0
));
799 printf("CSC1 : %lx\n",AROS_LONG2BE(Regs
.CSC1
));
800 printf("CSC2 : %lx\n",AROS_LONG2BE(Regs
.CSC2
));
801 printf("CSC3 : %lx\n",AROS_LONG2BE(Regs
.CSC3
));
804 Not doing
this anymore
. Will
do this on the palm
.
806 * Disable the read only bit in the CSA1 and CSA3 register.
808 Regs
.CSA1
&= AROS_LONG2BE(0xfffffff7);
809 printf("Changing CSA1 register to new value %x!\n",AROS_LONG2BE(Regs
.CSA1
));
810 err
= write_mem(IORequest
, 0xfffff110, (char *)&Regs
.CSA1
, sizeof(Regs
.CSA1
));
812 printf("Successfully changed register CSA1!\n");
815 Regs
.CSA3
&= AROS_LONG2BE(0xfffffff7);
816 printf("Changing CSA3 register to new value %x!\n",AROS_LONG2BE(Regs
.CSA3
));
817 err
= write_mem(IORequest
, 0xfffff110, (char *)&Regs
.CSA3
, sizeof(Regs
.CSA3
));
819 printf("Successfully changed register CSA3!\n");
822 BuildPilotMem(&Regs
);
823 printf("Trying to upload program now!\n");
824 if (0 != upload_program(IORequest
,filename
, &startaddr
)) {
825 printf("upload_program returned error!\n");
829 start_program(IORequest
, startaddr
);
831 send_packet(IORequest
, (char *)&err
, 1, TYPE_QUIT
);