semihosting: initial implementation of ARM semihosting

Useful for logging output to the host console.
This commit is contained in:
Ayke van Laethem
2019-10-30 14:09:40 +01:00
committed by Ron Evans
parent e0cdc931e7
commit 2e606b090a
2 changed files with 67 additions and 0 deletions
+47
View File
@@ -0,0 +1,47 @@
// Package semihosting implements parts of the ARM semihosting specification,
// for communicating over a debug connection.
//
// If you want to use it in OpenOCD, you have to enable it first with the
// following command:
//
// arm semihosting enable
package semihosting
import (
"device/arm"
"unsafe"
)
// IOError is returned by I/O operations when they fail.
type IOError struct {
BytesWritten int
}
func (e *IOError) Error() string {
return "semihosting: I/O error"
}
// Write writes the given data to the given file descriptor. It returns an
// *IOError if the write was not successful.
func Write(fd uintptr, data []byte) error {
if len(data) == 0 {
return nil
}
params := struct {
fd uintptr
data unsafe.Pointer
len int
}{
fd: fd,
data: unsafe.Pointer(&data[0]),
len: len(data),
}
unwritten := arm.SemihostingCall(arm.SemihostingWrite, uintptr(unsafe.Pointer(&params)))
if unwritten != 0 {
// Error: unwritten is the number of bytes not written.
return &IOError{
BytesWritten: len(data) - unwritten,
}
}
return nil
}
+20
View File
@@ -0,0 +1,20 @@
package semihosting
// These three file descriptors are connected to the host stdin/stdout/stderr,
// and can be used for logging.
var (
Stdin = File{fd: 0}
Stdout = File{fd: 1}
Stderr = File{fd: 2}
)
// File represents a semihosting file descriptor.
type File struct {
fd uintptr
}
// Write writes the given data buffer to the file descriptor, returning an error
// if the write could not complete successfully.
func (f *File) Write(buf []byte) error {
return Write(f.fd, buf)
}